JWT生成与解析/JWT令牌前端存储

第一步:创建项目

添加Maven依赖:

<dependency>
    <groupId>com.alibabagroupId>
    <artifactId>fastjsonartifactId>
    <version>1.2.62version>
dependency>
<dependency>
    <groupId>org.springframework.bootgroupId>
    <artifactId>spring-boot-starter-webartifactId>
dependency>
<dependency>
    <groupId>io.jsonwebtokengroupId>
    <artifactId>jjwt-apiartifactId>
    <version>0.11.2version>
dependency>
<dependency>
    <groupId>io.jsonwebtokengroupId>
    <artifactId>jjwt-implartifactId>
    <version>0.11.2version>
    <scope>runtimescope>
dependency>
<dependency>
    <groupId>io.jsonwebtokengroupId>
    <artifactId>jjwt-jacksonartifactId>
    <version>0.11.2version>
    <scope>runtimescope>
dependency>

<dependency>
    <groupId>org.springframework.bootgroupId>
    <artifactId>spring-boot-starter-thymeleafartifactId>
dependency>
<dependency>
    <groupId>net.sourceforge.nekohtmlgroupId>
    <artifactId>nekohtmlartifactId>
    <version>1.9.22version>
dependency>

在resources/static目录下创建js文件夹,然后在其中添加jquery3.3.1.js文件

在这里插入图片描述

编辑application.yml:

server:
    port: 80
    servlet:
        context-path: /jwt
spring:
    thymeleaf:
        #前缀,也就是模板存放的路径
        prefix: classpath:/templates/
        #编码格式
        encoding: UTF-8
        check-template-location: false
        #关闭缓存,不然无法看到实时页面
        cache: false
        #后缀
        suffix: .html
        #设置不严格的html
        mode: HTML
        servlet:
            content-type: text/html

第二步:创建表示用户的实体类:

@Getter
@Setter
@ToString
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class User implements Serializable {
    private static final long serialVersionUID = -8390887042859558153L;
    private Integer id;
    private String username;
    private String password;
}

第三步:创建常量类:

public interface JwtConst {
    //JWT签发者
    String JWT_ID = "098f6bcd4621d373cade4e832627b4f6";
    // 密钥, 经过Base64加密, 可自行替换
    String JWT_SECRECT = "MDk4ZjZiY2Q0NjIxZD";
    // 过期时间,单位毫秒
    int JWT_TTL = 60*60*1000;
}

第四步:Jwt工具类:

public class JwtUtil {
   private static Key key =  Keys.secretKeyFor(SignatureAlgorithm.HS256);
    public static String createJWT(String id, String subject, int ttl) {
        Calendar calendar = Calendar.getInstance();
        JwtBuilder builder = Jwts.builder()
                .setId(id)  //JWT唯一标识
                .setIssuedAt(calendar.getTime()) //签发时间
                .setSubject(subject) //JWT的主题,比如JSON类型的User对象
                .signWith(key);
        calendar.add(Calendar.MINUTE, ttl); // ttl过期时间,单位分钟
        builder.setExpiration(calendar.getTime()); //过期时间
        return builder.compact();
    }
    public static Claims parseJwt(String jwt){
        Claims claims = Jwts.parserBuilder().setSigningKey(key)
.build().parseClaimsJws(jwt).getBody();
        return claims;
    }
    public static String createSubject(User user){
        return JSON.toJSONString(user);
    }
}

第五步:创建表示服务器端返回结果的类:

@Data
@NoArgsConstructor
@AllArgsConstructor
public class Result<T> {
    private int code;
    private String msg;
    private T data;
    public Result(int code, String msg) {
        this.code = code;
        this.msg = msg;
    }
}

第六步:创建Controller:

生成、解析JWT的Controller

@Controller
@RequestMapping("/jwt")
public class JWTController {
    @RequestMapping("/login")
    @ResponseBody
    public Result<String> login(String username, String password) {
        if (username == null || password == null) {
            return new Result<String>(789, "用户名或密码不正确", null);
        }
        User user = new User(1001, username, password);
        String jwt = JwtUtil.createJWT(JwtConst.JWT_ID, 
JwtUtil.createSubject(user), JwtConst.JWT_TTL);
        System.out.println(jwt);
        return new Result<>(200, "请求成功!", jwt);
    }
    @RequestMapping("/parseJwt")
    @ResponseBody
    public User parseJwt(HttpServletRequest request) {
        String jwt = request.getHeader("Authorization");
        String token = JSON.parseObject(jwt).getString("token");
        Claims claims = JwtUtil.parseJwt(token);
        String subject = claims.getSubject();
        User user = JSON.parseObject(subject, User.class);
        System.out.println(user);
        return user;
    }
}

页面分发的Controller:

@Controller
public class DispatchController {
    @GetMapping("/login")
    public String showLogin(){
        return "/login";
    }
    @GetMapping("/showJwt")
    public String showJwt(){
        return "showJwt";
    }
    @GetMapping("/index")
    public String index(){
        return "index";
    }
}

第七步:前端页面:

login.html

DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>登录页面title>
        <script src="js/jquery3.5.1.js" type="text/javascript">script>
    head>
    <body>
        <form id="loginForm">
            <input type="text" name="username" value="zhangsan"><br>
            <input type="password" name="password" value="123456">
        form>
        <button id="btn">登录button>
        <script>
            $(function () {
                $("#btn").click(function () {
                    $.ajax({
                        type: "POST",//请求方式
                        url: "jwt/login",  //请求地址
                        dataType: "JSON", //预期服务器端返回的数据的类型
                        data: $("#loginForm").serialize(),//数据,json字符串
                        success: function (result) { //请求成功
                            console.log(result);
                            if (result.code == 200) {
                                //获取令牌并保存到本地
                                localStorage.setItem("token", '{"token":"' + result.data + '"}');
                            }
                            if (result.code == 789) {
                                window.location = "login";
                            }
                        },
                        error: function (e) {  //请求失败,包含具体的错误信息
                            console.log(e.status);
                            console.log(e.responseText);
                        }
                    });
                });
            });
        script>
    body>
html>

注:第一次点登录按钮时,无法将token数据保存在Application中,原因未找到,发现原因的朋友麻烦告诉我一声。

index.html

DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>首页title>
        <script src="js/jquery3.3.1.js" type="text/javascript">script>
    head>
    <body>
        首页启动时请求后台的解析Jwt的的请求
        <div id="sh">div>
        <script>
            $(function () {
                $.ajax({
                    url: "jwt/parseJwt",
                    headers: {Authorization: localStorage.getItem("token")},
                    success:function (res) {
                        console.info(res);
                        $("#sh").text(JSON.stringify(res));
                    }
                })
            });
        script>
    body>
html>

第八步:部署运行查看结果:

  1. 访问http://localhost/jwt/login,在打开的login.html页面中单击登录按钮:
    JWT生成与解析/JWT令牌前端存储_第1张图片

注:第一次点登录按钮时,无法将token数据保存在Application中,原因未找到。
2. 访问http://localhost/jwt/index,在页面上会看到:
JWT生成与解析/JWT令牌前端存储_第2张图片

你可能感兴趣的:(SpringBoot,jwt,token)