JWT安全认证,速度学会上手

文章介绍了Web认证的两种常见方式:Session认证及其存在的扩展性问题,以及Token认证特别是JWT(JSONWebToken)的实现过程和优势。通过JWT,服务端无需存储session数据,通过签名token来确保数据安全。
摘要由CSDN通过智能技术生成

1.Session认证


1.1 认证过程

用户----发送用户名和密码—>服务器

服务器: 验证通过后,在当前对话(session)里面保存相关数据,比如用户角色、登录时间等。

服务器---- 返回一个 session_id----->用户: 写入用户的 Cookie。

用户----发送请求,传回cookie中的session_id–>服务器

服务器 -----根据session_id查询到用户信息,返回user----> 用户


1.2 缺陷

session 认证的方式应用非常普遍,但也存在一些问题,扩展性不好。如果是服务器集群,或者是跨域的服务导向架构,就要求 session 数据共享,每台服务器都能够读取 session。

1.3 解决方法

way1:

session 数据持久化,写入数据库或别的持久层。各种服务收到请求后,都向持久层请求数据。这种方案的优点是架构清晰,缺点是工程量比较大。

way2:

所有数据都保存在客户端,服务器不再保存 session 数据,每次请求都发回服务器。Token认证就是这种方案的一个代表。



2.Token认证

Token 是在服务端产生的一串字符串,是客户端访问资源接口(API)时所需要的资源凭证。


2.1 认证过程

用户----发送用户名和密码—>服务器

服务器---- 验证通过后,签发一个token ----->用户: 存储起来(cookie/localStorage)

用户----发送请求,传回token–>服务器

服务器 -----解析token,查询到用户信息,返回user----> 用户


2.2 特点

服务端no数据:基于 token 的用户认证是一种服务端无状态的认证方式,服务端不用存放 token 数据。

时间换空间:用解析 token 的计算时间换取 session 的存储空间,从而减轻服务器的压力,减少频繁的查询数据库

token 完全由应用管理,所以它可以避开同源策略



3. JWT实现token认证


3.1 JWT组成

  • Header(头部):描述 JWT 的元数据
    • (alg:签名算法;type:JWT)
  • Payload(负载):存放实际需要传递的数据
    • issuer(签发人)、expiration(过期时间)、subject(主题)、audience(受众)、Not Before(生效时间)、issued At(签发时间)、JWTID(编号)
  • Signature(签名):对前两部分的签名,防止数据篡改
    • 指定secret(密钥),安装头部的签名算法将密钥生成签名。

3.2 使用流程

step1:加入依赖

<!--JWT认证-->
<dependency>
    <groupId>io.jsonwebtoken</groupId>
    <artifactId>jjwt</artifactId>
    <version>0.9.1</version>
</dependency>

step2:封装成JwtUtils工具类

public class JwtUtils {
    //7天过期(自定义)
    private static long expire = 604800;
    //32位秘钥(自定义)
    private static String secret = "asdfghjklzxcvbnmlkjhgfdsazxcvbnm";
    
    //生成token
    public static String generateToken(String subject){
        //....
    }

    //解析token
    public static Claims getClaimsByToken(String token){
       // ....
    }
    
    //....
}
生成token
//生成token
public static String generateToken(String subject){
    Date now = new Date();
    Date expiration = new Date(now.getTime() + 1000 * expire);
    return Jwts.builder()
        .setHeaderParam("type","JWT")
        .setSubject(subject)
        .setIssuedAt(now)
        .setExpiration(expiration)
        .signWith(SignatureAlgorithm.HS256,secret)
        .compact();
}
解析token
//解析token
public static Claims getClaimsByToken(String token){
    return Jwts.parser()
        .setSigningKey(secret)
        .parseClaimsJws(token)
        .getBody();
}
//解析token获取其subject
public static String  getSubjectByToken(String token){
    return JwtUtils.getClaimsByToken(token).getSubject();
}

step3:使用JwtUtils进行token认证

登录认证
//jwt登录认证
@RequestMapping("login")
public JsonResult<String> login(int id, String password){
    //认证密码正确与否
    User user = service.login(id, password);
    //获取token
    String token = JwtUtils.generateToken(user.getId().toString());
    //返回token
    return new JsonResult<String>(OK,token);
}
获取信息
//获取用户信息
@RequestMapping("getUser")
public JsonResult<User> getUser(String token){

    //解析token获取用户id
    String subject = JwtUtils.getSubjectByToken(token);

    //根据id获取数据库的user信息
    User user = service.getById(userId);
    return new JsonResult<User>(OK,user);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值