jwt的使用

前言

在进行身份认证时,一般会考虑两种方案,一是使用session,二是使用jwt。而使用session这个方案通常会产生一些比较棘手的问题,那就是跨域。而使用jwt则可以完美避开跨域的问题。下面我来实际使用jwt方案。

后端

一、准备依赖

        <dependency>
            <groupId>com.auth0</groupId>
            <artifactId>java-jwt</artifactId>
            <version>3.9.0</version>
        </dependency>
        <dependency>
            <groupId>org.json</groupId>
            <artifactId>json</artifactId>
            <version>20190722</version>
        </dependency>
                <!-- https://mvnrepository.com/artifact/com.google.code.gson/gson -->
        <dependency>
            <groupId>com.google.code.gson</groupId>
            <artifactId>gson</artifactId>
            <version>2.9.1</version>
        </dependency>

二、建表

create table if not exists token
(
    id              bigint auto_increment comment 'id' primary key,
    token            varchar(512)       not null comment 'token'
);

三、操作token

TokenMapper.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.lzj.qqbackend.mapper.TokenMapper">

    <resultMap id="BaseResultMap" type="com.lzj.qqbackend.model.bean.Token">
            <id property="id" column="id" jdbcType="BIGINT"/>
            <result property="token" column="token" jdbcType="VARCHAR"/>
    </resultMap>

    <sql id="Base_Column_List">
        id,token
    </sql>
    <insert id="insertOrUpdate">
        INSERT INTO qq.token (id, token)
        VALUES (#{id}, #{token})
        <if test="id != null">
            ON DUPLICATE KEY UPDATE
            token = #{token}
        </if>
    </insert>
</mapper>

TokenMapper

package com.lzj.qqbackend.mapper;

import com.lzj.qqbackend.model.bean.Token;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Select;

/**
* @author 赖志军
* @description 针对表【token(token表)】的数据库操作Mapper
* @createDate 2023-11-24 17:04:13
* @Entity com.lzj.qqbackend.model.bean.Token
*/
public interface TokenMapper extends BaseMapper<Token> {
    @Select("select id from 数据库名称.token where token = #{token}")
    Long getTokenId(String token);

    void insertOrUpdate(Long id,String token);
}

实体类Token

package com.lzj.qqbackend.model.bean;

import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import java.io.Serializable;
import lombok.Data;

/**
 * token表
 * @TableName token
 */
@TableName(value ="token")
@Data
public class Token implements Serializable {
    /**
     * id
     */
    @TableId
    private Long id;

    /**
     * token字符串
     */
    private String token;

    @TableField(exist = false)
    private static final long serialVersionUID = 1L;
}

!!!注意上面的代码需要根据自己的项目进行修改。就是生成一个操作token表的mapper。这一部分代码也可以不使用,也可使用jwt。这个代码可以用来无感刷新token,这里就不多说了。

四、token工具类

package com.lzj.sweetsManger.utils;
import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.JWTCreationException;
import com.auth0.jwt.exceptions.JWTDecodeException;
import com.auth0.jwt.exceptions.JWTVerificationException;
import com.auth0.jwt.interfaces.DecodedJWT;
import com.google.gson.Gson;
import com.lzj.sweetsManger.mapper.TokenMapper;
import com.lzj.sweetsManger.model.vo.UserVO;

import javax.annotation.Resource;
import java.util.Date;

public class TokenUtils {
 
    //token到期时间10小时
    private static final long EXPIRE_TIME= 10*60*60*1000;
    //密钥盐
    private static final String TOKEN_SECRET="ljdyaishijin**3nkjnj??";
    @Resource
    private TokenMapper tokenMapper;
    /**
     * 生成token
     * @param userVO
     * @return
     */
    public static String sign(UserVO userVO){
        String token=null;
        try {
            Date expireAt=new Date(System.currentTimeMillis()+EXPIRE_TIME);
            Gson gson = new Gson();
            String userVoJSON = gson.toJson(userVO);
            token = JWT.create()
                    //发行人
                    .withIssuer("auth0")
                    //存放数据
                    .withClaim("userVO",userVoJSON)
                    //过期时间
                    .withExpiresAt(expireAt)
                    .sign(Algorithm.HMAC256(TOKEN_SECRET));
        } catch (IllegalArgumentException| JWTCreationException je) {
 
        }
        return token;
    }
 
 
    /**
     * token验证
     * @param token
     * @return
     */
    public static Boolean verify(String token){
        try {
            //创建token验证器
            JWTVerifier jwtVerifier=JWT.require(Algorithm.HMAC256(TOKEN_SECRET)).withIssuer("auth0").build();
            DecodedJWT decodedJWT=jwtVerifier.verify(token);
        } catch (IllegalArgumentException | JWTVerificationException e) {
            //抛出错误即为验证不通过
            return false;
        }
        return true;
    }
    //获取存储的用户信息
    public static UserVO getUserVO(String token){
            try {
                DecodedJWT jwt = JWT.decode(token);
                String userVOStr = jwt.getClaim("userVO").asString();
                Gson gson = new Gson();
                return gson.fromJson(userVOStr,UserVO.class);
            } catch (JWTDecodeException e) {
                return null;
            }
    }
 
}

五、使用

在用户登录时,使用token工具类中的sign方法生成token并返回token给前端。

前端

一、配置axios

在登录成功时,存储token, localStorage.setItem(“token”,res.data.token)

axios.defaults.headers.common['Authorization'] = localStorage.getItem("token");

总结

ok了,有不懂的,可以在评论区问我。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值