使用JWT生成token,实现单点登录

本文介绍了如何使用Java-JWT库实现用户登录后的token生成、验证,并展示了如何在前后端交互中应用JWT。通过MD5加密处理密码,确保安全。重点涉及前端请求携带token,后端验证及token有效期管理。
摘要由CSDN通过智能技术生成

1、引入相关依赖

<!-- https://mvnrepository.com/artifact/com.auth0/java-jwt -->
   <dependency>
       <groupId>com.auth0</groupId>
       <artifactId>java-jwt</artifactId>
       <version>3.15.0</version>
   </dependency>

2、创建一个工具类,用于生成和验证token

public class JwtUtils {

    public static final long EXPIRE=1000*60*60*24; //token过期时间

    public static final String APP_SECRET="密钥"; //密钥

    /**
     * 生成token
     * @param id
     * @param nickname 昵称
     * @return
     */
    public static String getJwtToken(String id,String nickname){
        Algorithm algorithm=Algorithm.HMAC256(APP_SECRET);
        Map<String,Object> headerClaims=new HashMap<>();
        headerClaims.put("typ","JWT");
        headerClaims.put("alg","HS256");
        String JwtToken= JWT.create()
                .withHeader(headerClaims)
                .withAudience("guli-user")
                .withIssuedAt(new Date())
                .withExpiresAt(new Date(System.currentTimeMillis()+EXPIRE))
                .withClaim("id",id)
                .withClaim("nickname",nickname)
                .sign(algorithm);
        return JwtToken;
    }

    /**
     * 验证token
     * @param jwtToken
     * @return true 验证成功
     *         false 验证失败
     */
    public static boolean checkToken(String jwtToken){
        if (ObjectUtils.isEmpty(jwtToken)){
            return false;
        }
        Algorithm algorithm=Algorithm.HMAC256(APP_SECRET);
        JWTVerifier verifier=JWT.require(algorithm).build();
        try {
            verifier.verify(jwtToken);
        }catch (JWTVerificationException exception){
            exception.printStackTrace();
            return false;
        }
        return true;
    }

    /**
     * 验证token
     * @param request
     * @return true 验证成功
     *         false 验证失败
     */
    public static boolean checkToken(HttpServletRequest request){
        String jwtToken=request.getHeader("token");
        if (ObjectUtils.isEmpty(jwtToken)){
            return false;
        }
        Algorithm algorithm=Algorithm.HMAC256(APP_SECRET);
        JWTVerifier verifier=JWT.require(algorithm).build();
        try {
            verifier.verify(jwtToken);
        }catch (JWTVerificationException exception){
            exception.printStackTrace();
            return false;
        }
        return true;
    }

    /**
     * 通过token获取id
     * @param request
     * @return
     */
    public static String getMemberIdByJwtToken(HttpServletRequest request){
        String jwtToken=request.getHeader("token");
        if (ObjectUtils.isEmpty(jwtToken)){
            return "";
        }
        String id = JWT.decode(jwtToken).getClaim("id").asString();
        return id;
    }
}

3、写登录接口,登录成功后生成token发送给客户端

@PostMapping("/login")
public R loginUser(@RequestBody UcenterMember member){
     String token = memberService.login(member);
     return R.ok().data("token",token);
 }
@Override
public String login(UcenterMember member) {
    String mobile=member.getMobile(); //手机号
    String password=member.getPassword(); //密码
    //判断手机号和密码是否为空
    if (ObjectUtils.isEmpty(mobile) || ObjectUtils.isEmpty(password)){
        throw new GuliException(20001,"登录失败");
    }
    QueryWrapper<UcenterMember> wrapper=new QueryWrapper<>();
    wrapper.eq("mobile",mobile);
    UcenterMember ucenterMember = baseMapper.selectOne(wrapper);
    if (ucenterMember==null){
        throw new GuliException(20001,"登录失败");
    }
    if (!MD5.encrypt(password).equals(ucenterMember.getPassword())){
        throw new GuliException(20001,"登录失败");
    }
    if (ucenterMember.getIsDisabled()){
        throw new GuliException(20001,"登录失败");
    }
    String jwtToken = JwtUtils.getJwtToken(ucenterMember.getId(), ucenterMember.getNickname());

    return jwtToken;
}

其中,MD5是一个工具类,用于对密码进行加密

public final class MD5 {

    public static String encrypt(String strSrc) {
        try {
            char hexChars[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8',
                    '9', 'a', 'b', 'c', 'd', 'e', 'f' };
            byte[] bytes = strSrc.getBytes();
            MessageDigest md = MessageDigest.getInstance("MD5");
            md.update(bytes);
            bytes = md.digest();
            int j = bytes.length;
            char[] chars = new char[j * 2];
            int k = 0;
            for (int i = 0; i < bytes.length; i++) {
                byte b = bytes[i];
                chars[k++] = hexChars[b >>> 4 & 0xf];
                chars[k++] = hexChars[b & 0xf];
            }
            return new String(chars);
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
            throw new RuntimeException("MD5加密出错!!+" + e);
        }
    }
}

客户端发请求,需要带上token,服务端会进行解密,验证token是否正确。如果token是正确的,说明用户处于登录状态。随意伪造的token是不能被解密的,会抛出异常。

Web前端实现流程

1、登录页获取表单信息发送Ajax请求,后端获取请求数据,生成token,再将token作为响应数据发送给前端。
2、前端获取token,存入cookie,再将cookie中的token取出,作为请求头发送给后端服务器。这一步可以使用axios中的拦截器实现,每次请求都从cookie中取出token,可以先判断cookie中的token是否存在
3、后端获取token,进行解密,得到用户的id,再根据id查询数据库,得到完整的用户信息,再将用户信息发送给前端。
4、前端得到用户信息,存入cookie,然后进行页面跳转,再将cookie中的用户信息取出,在网页上进行显示。

用户退出时,只要将相关的cookie删除就可以了,再进行页面跳转或刷新,或者再将vue中的用户属性置为空。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值