小程序(二)shiro+jwt登录认证


一、Shiro和JWT技术

Shiro是Java领域非常知名的认证( Authentication )与授权
( Authorization )框架,用以替代JavaEE中的JAAS功能。相
较于其他认证与授权框架,Shiro设计的非常简单,所以广受好
评。任意JavaWeb项目都可以使用Shiro框架,而Spring Security
必须要使用在Spring项目中。所以Shiro的适用性更加广泛。像什
么 JFinal 和 Nutz 非Spring框架都可以使用Shiro,而不能使用Spring Security框架。


1、Shiro简介

什么是认证?
认证就是要核验用户的身份,比如说通过用户名和密码来检验用户的身份。说简单一些,认证就
是登陆。登陆之后Shiro要记录用户成功登陆的凭证。

什么是授权?
授权是比认证更加精细度的划分用户的行为。比如说一个教务管理系统中,学生登陆之后只能查
看信息,不能修改信息。而班主任就可以修改学生的信息。这就是利用授权来限定不同身份用户
的行为。

Shiro靠什么做认证与授权?
Shiro可以利用 HttpSession 或者 Redis 存储用户的登陆凭证,以及角色或者身份信息。然后利
用过滤器(Filter),对每个Http请求过滤,检查请求对应的 HttpSession 或者 Redis 中的认证
与授权信息。如果用户没有登陆,或者权限不够,那么Shiro会向客户端返回错误信息。
也就是说,我们写用户登陆模块的时候,用户登陆成功之后,要调用Shiro保存登陆凭证。然后查
询用户的角色和权限,让Shiro存储起来。将来不管哪个方法需要登陆访问,或者拥有特定的角色
跟权限才能访问,我们在方法前设置注解即可,非常简单。

2、JWT简介

JWT(Json Web Token), 是为了在网络应用环境间传递声明而执行的一种基于JSON的开放标
准。JWT一般被用来在身份提供者和服务提供者间传递被认证的用户身份信息,以便于从资源服
务器获取资源,也可以增加一些额外的其它业务逻辑所必须的声明信息,该token也可直接被用
于认证,也可被加密。
在这里插入图片描述
JWT可以用在单点登录的系统中:
传统的 JavaWeb 项目,利用 HttpSession 保存用户的登陆凭证。如果后端系统采用了负载均衡
设计,当用户在A节点成功登陆,那么登陆凭证保存在A节点的 HttpSession 中。如果用户下一
个请求被负载均衡到了B节点,因为B节点上面没有用户的登陆凭证,所以需要用户重新登录,
这个体验太糟糕了。
在这里插入图片描述
如果用户的登陆凭证经过加密( Token )保存在客户端,客户端每次提交请求的时候,把
Token 上传给后端服务器节点。即便后端项目使用了负载均衡,每个后端节点接收到客户端上传
的Token之后,经过检测,是有效的 Token ,于是就断定用户已经成功登陆,接下来就可以提供
后端服务了。
在这里插入图片描述
JWT兼容更多的客户端:
传统的 HttpSession 依靠浏览器的 Cookie 存放 SessionId ,所以要求客户端必须是浏览器。现
在的JavaWeb系统,客户端可以是浏览器、APP、小程序,以及物联网设备。为了让这些设备都
能访问到JavaWeb项目,就必须要引入JWT技术。JWT的 Token 是纯字符串,至于客户端怎么
保存,没有具体要求。只要客户端发起请求的时候,附带上 Token 即可。所以像物联网设备,我
们可以用 SQLite 存储 Token 数据

二、创建JWT工具类

JWT的 Token 要经过加密才能返回给客户端,包括客户端上传的 Token ,后端项目需要验证核
实。于是我们需要一个JWT工具类,用来 加密Token 和 验证Token 的有效性。

1、导入依赖库

        <dependency>
            <groupId>com.auth0</groupId>
            <artifactId>java-jwt</artifactId>
            <version>3.3.0</version>
        </dependency>
        <!--shiro-->
        <dependency>
            <groupId>org.apache.shiro</groupId>
            <artifactId>shiro-spring-boot-starter</artifactId>
            <version>1.5.3</version>
        </dependency>
        <!--hutool jar-->
        <dependency>
            <groupId>cn.hutool</groupId>
            <artifactId>hutool-all</artifactId>
            <version>5.0.7</version>
        </dependency>

        <!--考虑到Hutool的非强制依赖性,因此zxing需要用户自行引入-->
        <dependency>
            <groupId>com.google.zxing</groupId>
            <artifactId>core</artifactId>
            <version>3.4.0</version>
        </dependency>
        <dependency>
            <groupId>com.google.zxing</groupId>
            <artifactId>javase</artifactId>
            <version>3.4.0</version>
        </dependency>

2、定义密钥和过期时间

我建议大家把密钥和过期时间定义到SpringBoot配置文件中,然后再值注入到JavaBean中,这样
维护起来比较方便。

WeChatMiNi:
  jwt:
    #密钥
    secret: buba123456
    #令牌期时间
    expire: 7
    #令牌缓存时间(天)
    cache-expire: 10

3、创建JWT工具类

package com.buba.wechatmini.common.utils;

/**
 * @author qlx
 */


import com.buba.wechatmini.exception.WechatminiException;
import cn.hutool.core.date.DateField;
import cn.hutool.core.date.DateUtil;
import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTCreator;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.interfaces.DecodedJWT;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import java.io.UnsupportedEncodingException;
import java.util.Date;

@Component
@Slf4j
public class JwtUtil {
   
    //密钥
    @Value("${WeChatMiNi.jwt.secret}")
    private String secret;
    //过期时间(天)
    @Value("${WeChatMiNi.jwt.expire}")
    private int expire;

    public String createToken(int userId) throws UnsupportedEncodingException {
   
//         @param date 基准日期
//         @param dateField 偏移的粒度大小(小时、天、月等){@link DateField}
//         @param offset 偏移量,正数为向后偏移,负数为向前偏移
//         @return 偏移后的日期
        Date date = DateUtil.offset(new Date(), DateField.DAY_OF_YEAR,expire).toJdkDate();
        Algorithm algorithm = Algorithm.HMAC256(secret); //创建加密算法对象
        JWTCreator.Builder builder = JWT.create();
        String token = builder.withClaim("userId",userId).withExpiresAt(date).sign(algorithm);
        return token;
    }
    public int getUserId(String token) {
   
        try {
   
            DecodedJWT jwt = JWT.decode(token);
            return jwt.getClaim("userId").asInt();
        } catch (Exception e) {
   
            thr
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
ShiroJWT是两个不同的技术,可以结合使用来实现认证和授权功能。 Shiro是一个Java领域非常知名的认证和授权框架,用于替代JavaEE中的JAAS功能。相较于其他框架,Shiro设计简单,适用性广泛。任何JavaWeb项目都可以使用Shiro框架,包括非Spring框架的项目,如JFinal和Nutz。Shiro可以用于保存登录凭证、查询用户角色和权限,并通过注解来限制方法的访问权限。\[1\] JWT(JSON Web Token)是一种用于身份验证的技术。传统的HttpSession依赖于浏览器的Cookie存放SessionId,要求客户端必须是浏览器。而JWT的Token是纯字符串,可以被任何客户端使用,包括浏览器、APP、小程序和物联网设备。客户端在发起请求时,只需附带上Token即可,而无需特定的存储方式。例如,物联网设备可以使用SQLite存储Token数据。\[2\] 因此,结合ShiroJWT可以实现更灵活的认证和授权功能。Shiro负责处理用户登录、角色和权限的管理,而JWT负责生成和验证身份令牌。通过结合使用,可以实现跨平台、跨设备的身份验证和授权功能。 #### 引用[.reference_title] - *1* *2* *3* [ShiroJWT简介](https://blog.csdn.net/lad_z/article/details/129240771)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值