springboot jwt token 登录

基本概念:

jwt(json web token):是一种紧凑、URL安全的方法,用于表示双方之间要传输的声明.
JWT 由 3 部分构成:

  1. Header : 描述 JWT 的元数据,定义了生成签名的算法以及 Token 的类型。
  2. Payload : 用来存放实际需要传递的数据
  3. Signature(签名) :服务器通过Payload、Header和一个密钥(secret)使用 Header 里面指定的签名算法(默认是 HMAC SHA256)生成。

具体流程

  1. 用户使用用户名密码来请求服务器
  2. 服务器进行验证用户的信息
  3. 服务器通过验证发送给用户一个token
  4. 客户端存储token(可以放在cookie或者localstorge),并在每次请求时附送上这个token值
  5. 服务端验证token值,并返回数据

springboot 详细配置

pom

加一个maven配置

        <dependency>
            <groupId>com.auth0</groupId>
            <artifactId>java-jwt</artifactId>
            <version>3.4.0</version>
        </dependency>

token utils

这里主要由两个功能 生成token,和验证token

生成token

  1. 向token添加数据 2.设置过期时间 3.添加加密算法

token一般添加的数据 (建议但不强制使用) :
iss: jwt签发者
sub: jwt所面向的用户
aud: 接收jwt的一方
exp: jwt的过期时间,这个过期时间必须要大于签发时间
nbf: 定义在什么时间之前,该jwt都是不可用的.
iat: jwt的签发时间
jti: jwt的唯一身份标识,主要用来作为一次性token,从而回避重放攻击。

验证token

1.通过解密方法解密

@Component
public class TokenUtil {

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

    /**
     * 签名生成
     * @return
     */
    public static String sign(String name){

        String token = null;
        try {
            Date expiresAt = new Date(System.currentTimeMillis() + EXPIRE_TIME);
            token = JWT.create()
                    .withIssuer("auth0").withClaim("id","id")
                    .withClaim("username", name)
                    .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("id"+jwt.getClaim("id").asString());
            System.out.println("过期时间:      " + jwt.getExpiresAt());
            return true;
        } catch (Exception e){
            return false;
        }
    }
}

controller

@RestController
public class LoginController {
    @RequestMapping("/login")
    public String login(HttpSession session, String name, String password){
        System.out.println(name);
        System.out.println(password);
        // 这个需要查数据库判断用户名和密码是否正确
        if(Objects.equals(name, "xx") && Objects.equals(password, "xx"))
        {
            String res = TokenUtil.sign("xx");
            System.out.println(res);
            return "成功:"+res;
        }
        return "失败";

    }
    @RequestMapping("/index")
    public String index(){
        return "登录";
    }
}

@RestController
public class TestController {

    @RequestMapping("/hello")
    public String helloWorld(){
        return "hello world";
    }
    @RequestMapping("/hello02")
    public String helloWorld02(){
        return "hello world 02";
    }
}

过滤器

得到ajax传过来的header,验证token是否正确

public class LoginInterceptor implements HandlerInterceptor {
    // 这里我们也可以放在redis


    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        // 如果我们的map有浏览器存过来的sessionid我们就任务他是已经登录了。
        String token = request.getHeader("admin-token");
        if(TokenUtil.verify(token)){
            return true;
        }
        // 失败我们跳转新的页面
        request.setAttribute("msg","登录出错");
        request.getRemoteHost();
        request.getRequestDispatcher("/index").forward(request,response);
        return false;
    }

}

过滤器配置

@Configuration
public class InterceptorConfig {
    @Bean
    public MappedInterceptor loginInterceptor(){
        // 设置拦截器的作用域
        return new MappedInterceptor(new String[]{"/**"},new String[]{"/login","/index"},new LoginInterceptor());
    }
}

使用

posted @ 2022-03-29 16:44  度一川  阅读(748)  评论(0)    收藏  举报