springboot+jwt完成登录认证

本demo用于测试jwt,通过登录验证通过后,使用jwt生成token,然后在请求header中携带token完成访问用户列表信息。

准备工作:

1. 实体类SysUser.java

package com.king.entity;

import lombok.Data;

@Data
public class SysUser {

    private String id;
    private String username;
    private String password;

    public SysUser(String username,String password){
        this.username = username;
        this.password = password;
    }
}
View Code

2. 1 Service方法验证用户账号和密码(这里偷懒没写dao层)

2.2 Service方法获取用户列表

package com.king.service;

import com.king.entity.SysUser;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;

@Service
public class SysUserServiceImpl implements SysUserService{

    @Override
    public boolean login(SysUser user) {
        String username = user.getUsername();
        String password = user.getPassword();
        if(username.equals("king") && password.equals("123")){
            return true;
        }
        return false;
    }

    @Override
    public List<SysUser> getList() {

        SysUser user1= new SysUser("king1","12345");
        SysUser user2 = new SysUser("king2","12345");
        SysUser user3 = new SysUser("king3","12345");
        List<SysUser> list = new ArrayList<>();
        list.add(user1);
        list.add(user2);
        list.add(user3);
        return list;
    }
}
View Code

2.3 Service接口

package com.king.service;

import com.king.entity.SysUser;

import java.util.List;

public interface SysUserService {

    public boolean login(SysUser user);

    public List<SysUser> getList();
}
View Code

重点来了,接下来实现token工具类:

3. 使用jwt完成签名生成方法与验证方法

package com.king.util;

import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.interfaces.DecodedJWT;
import com.king.entity.SysUser;

import java.util.Date;

public class TokenUtil {

    private static final long EXPIRE_TIME= 15*60*1000;
    private static final String TOKEN_SECRET="token123";  //密钥盐


    /**
     * 签名生成
     * @param user
     * @return
     */
    public static String sign(SysUser user){

        String token = null;
        try {
            Date expiresAt = new Date(System.currentTimeMillis() + EXPIRE_TIME);
            token = JWT.create()
                    .withIssuer("auth0")
                    .withClaim("username", user.getUsername())
                    .withExpiresAt(expiresAt)
                    // 使用了HMAC256加密算法。
                    .sign(Algorithm.HMAC256(TOKEN_SECRET));
        } catch (Exception e){
            e.printStackTrace();
        }
        return token;

    }


    /**
     * 签名验证
     * @param token
     * @return
     */
    public static boolean verify(String token){


        try {
            JWTVerifier verifier = JWT.require(Algorithm.HMAC256(TOKEN_SECRET)).withIssuer("auth0").build();
            DecodedJWT jwt = verifier.verify(token);
            System.out.println("认证通过:");
            System.out.println("issuer: " + jwt.getIssuer());
            System.out.println("username: " + jwt.getClaim("username").asString());
            System.out.println("过期时间:      " + jwt.getExpiresAt());
            return true;
        } catch (Exception e){
            return false;
        }

    }



}

4. 添加拦截器

package com.king.interceptor;

import com.alibaba.fastjson.JSONObject;
import com.king.util.TokenUtil;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.PrintWriter;

@Component
public class TokenInterceptor implements HandlerInterceptor {



    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response,Object handler)throws Exception{

        if(request.getMethod().equals("OPTIONS")){
            response.setStatus(HttpServletResponse.SC_OK);
            return true;
        }

        response.setCharacterEncoding("utf-8");

        String token = request.getHeader("admin-token");
        if(token != null){
            boolean result = TokenUtil.verify(token);
            if(result){
                System.out.println("通过拦截器");
                return true;
            }
        }
        response.setCharacterEncoding("UTF-8");
        response.setContentType("application/json; charset=utf-8");
        PrintWriter out = null;
        try{
            JSONObject json = new JSONObject();
            json.put("success","false");
            json.put("msg","认证失败,未通过拦截器");
            json.put("code","50000");
            response.getWriter().append(json.toJSONString());
            System.out.println("认证失败,未通过拦截器");
            //        response.getWriter().write("50000");
        }catch (Exception e){
            e.printStackTrace();
            response.sendError(500);
            return false;
        }


        return false;

    }





}
View Code

5. 配置拦截器

package com.king.config;

import com.king.interceptor.TokenInterceptor;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

import java.util.ArrayList;
import java.util.List;

/**
 * 拦截器配置
 */
@Configuration
public class IntercepterConfig implements WebMvcConfigurer {

    private TokenInterceptor tokenInterceptor;

    //构造方法
    public IntercepterConfig(TokenInterceptor tokenInterceptor){
        this.tokenInterceptor = tokenInterceptor;
    }

    @Override
    public void addInterceptors(InterceptorRegistry registry){
        List<String> excludePath = new ArrayList<>();
        excludePath.add("/user_register"); //注册
        excludePath.add("/login"); //登录
        excludePath.add("/logout"); //登出
        excludePath.add("/static/**");  //静态资源
        excludePath.add("/assets/**");  //静态资源

        registry.addInterceptor(tokenInterceptor)
                .addPathPatterns("/**")
                .excludePathPatterns(excludePath);
        WebMvcConfigurer.super.addInterceptors(registry);

    }

}
View Code

6. controller层实现登录方法和获取用户列表方法

package com.king.controller;


import com.king.entity.SysUser;
import com.king.service.SysUserService;
import com.king.util.TokenUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

@RestController
public class UserController {


    @Autowired
    private SysUserService userService;


    @PostMapping(value="/login")
    @ResponseBody
    public Map<String,Object> login(String username,String password){

        Map<String,Object> map = new HashMap<>();
        SysUser user = new SysUser(username,password);

        if(userService.login(user)){
            String token = TokenUtil.sign(user);
            if(token != null){
                map.put("code", "10000");
                map.put("message", "认证成功");
                map.put("token", token);
                return map;
            }
        }

        map.put("code", "0000");
        map.put("message", "认证失败");
        return map;

    }

    @PostMapping(value="/getList")
    public List<SysUser> getList(){

        List userList = userService.getList();
        return userList;

    }



}
View Code

接下来测试:

1. 使用postman提交登录信息,当密码故意输错时,返回验证失败。

2. 提交正确的用户名和密码,验证通过,可以获取到token信息。

3. 使用token信息放到header中,key设置为admin-token,然后请求用户列表信息。

在后台我们可以看到token携带到用户信息和token的有效时间:

以上为整个jwt的使用流程。

原文地址:https://www.cnblogs.com/30go/p/10963924.html