JTW实现spring后端token验证

JTW实现spring后端token验证

基于之前的spring结合MongoDB的登录功能,添加了token验证的功能

上一个项目
首先展示一下项目的结构
项目结构
#####项目依赖

 <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
	
        <dependency>
            <groupId>org.mongodb</groupId>
            <artifactId>mongo-java-driver</artifactId>
            <version>3.12.11</version>
        </dependency>

        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>2.0.7</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-configuration-processor</artifactId>
            <optional>true</optional>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>io.jsonwebtoken</groupId>
            <artifactId>jjwt</artifactId>
            <version>0.9.1</version>
        </dependency>

        <dependency>
            <groupId>org.mongodb</groupId>
            <artifactId>bson</artifactId>
            <version>4.6.0</version>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>

        <dependency>
            <groupId>com.auth0</groupId>
            <artifactId>java-jwt</artifactId>
            <version>3.19.2</version>
        </dependency>
    </dependencies>
实体类部分
User.java
@Data
public class User{
    private String username;
    private String _id;
    private String password;
    private String token;//后端直接将token加入到实体类模型中
}
Msg.java
@Data
public class Msg<T> {
    private Integer code;//状态码
    private String msg;//信息
    private T data;//数据
    public static <T> Msg<T> success(T object){
        Msg<T> r = new Msg<>();
        r.data = object;
        r.code = 1;
        return r;
    }
    public static <T> Msg<T> error(String message){
        Msg r = new Msg();
        r.msg=message;
        r.code = 0;
        return r;
    }
}
工具类
DBUtil.java
@Slf4j
@Service
public class DBUtils {
    public static MongoCollection getCollection (String s){//根据传入的集合名称或许集合
        MongoClient mongoClient = new MongoClient("localhost",27017);
        MongoDatabase mongoDatabase = mongoClient.getDatabase("test");
        log.info("获取数据库成功:"+mongoDatabase);
        MongoCollection<Document> conn = mongoDatabase.getCollection(s);
        log.info("获取集合成功:"+mongoDatabase);
        return conn;
    }
}
JWTUtils.java
public class JWTUtils {
    public static String getToken(User user){

        Calendar calendar = Calendar.getInstance();//Calender为一个日期操作的类

        calendar.add(Calendar.DATE,1);//设置过期时间

        JWTCreator.Builder builder = JWT.create();
        builder.withClaim("_id",user.get_id())
                .withClaim("username",user.getUsername());//写入数据
        String token = builder.withExpiresAt(calendar.getTime()).sign(Algorithm.HMAC256(SIGNATURE));//生成token
        return token;
    }
    public static DecodedJWT verify(String token){
        DecodedJWT verify = JWT.require(Algorithm.HMAC256(SIGNATURE)).build().verify(token);
        return verify;
    }
}
Service层无更改,实现登录验证功能即可

这里直接将实现的类代码展示出来

UserServiceImpl.java
@Service
public class UserServiceImpl implements UserService {
    MongoCollection conn = DBUtils.getCollection("user");
    @Override
    public User findUserById(String _id) {
       FindIterable<Document> iterable = conn.find(new Document("_id",_id));
        MongoCursor<Document> cursor = iterable.iterator();
       if(cursor.hasNext()) {
           Document document = cursor.next();
           return JSON.parseObject(document.toJson(), User.class);
       } else{
            return null;
       }
    }
}
之后是拦截器的配置

拦截器验证则是直接根据前端发送的token令牌进行验证

JWTInterceptor.java
@Slf4j
public class JWTInterceptor implements HandlerInterceptor {
    @Override
    public  boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler){
        String token = request.getHeader("token");
        try {
            JWTUtils.verify(token);
        }catch (SignatureVerificationException e){
            e.printStackTrace();
            log.info("无效签名");
            return false;
        }catch (TokenExpiredException e){
            e.printStackTrace();
            log.info("token过期");
            return false;
        }catch (AlgorithmMismatchException e){
            e.printStackTrace();
            log.info("token算法不一致");
            return false;
        }catch (Exception e){
            e.printStackTrace();
            log.info("token无效");
            return false;
        }
        return true;
    }
}
IntercaptorConfig.java
@Configuration
public class IntercaptorConfig implements WebMvcConfigurer {

    public void addInterceptors(InterceptorRegistry registry){
        registry.addInterceptor((new JWTInterceptor()))
                .addPathPatterns("/**")//拦截所有api
                .excludePathPatterns("/login");//放行登录目录下的请求
    }
}
控制层
UserController.java
@Slf4j
@RestController
public class UserController {
    @Autowired
    UserServiceImpl service ;
    
    @PostMapping("/login")
    public Msg<User> login(@RequestBody User user){

        if(user!=null) log.info("后端成功接收User对象"+user);

        User o = service.findUserById(user.get_id());

        if(o==null){
            log.info("用户名不存在");
            return  Msg.error("用户不存在");
        }else {
            if(o.getPassword().equals(user.getPassword())){
                log.info("查询成功"+Msg.success(o));
                o.setToken(JWTUtils.getToken(o));
                o.setPassword(null);
                return  Msg.success(o);
            }else {
                log.info("密码错误,接受到的密码为:"+user.getPassword()+";正确密码为:"+o.getPassword());
                return Msg.error("密码错误");
            }
        }
    }
    @PostMapping("/verify")
    public String verify() {
        return "验证成功";
    }
项目测试
首先是直接访问Controller层写好的一个测试api

在这里插入图片描述
在这里插入图片描述

控制台给出了token无效的错误提示,说明拦截器成功拦截到了请求

之后进行一次正常登陆
请添加图片描述
这里已经可以得到后端返回的token了
然后使用返回的token再次验证
在这里插入图片描述
就可以正常访问了

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值