springboot+vue项目基础开发(三)登录接口

构造登录函数

在userController添加登录的构造函数

@PostMapping("login")
    public Result<String> login(@Pattern(regexp = "^\\S{5,16}$") String username,@Pattern(regexp = "^\\S{5,16}$")String password){
        //根据用户名查询用户
        User loginUser =userService.findByUserName(username);
        if(loginUser==null){
            return Result.error("用户名错误");
        }
        //判断密码是否正确 密码是密文
        if(MdUtil.getMDString(password).equals(loginUser.getPassword())){
            return Result.success("登录成功");
        }
        return Result.error("密码错误");
    }

在postman上进行登录

在这里插入图片描述

在这里插入图片描述

登录认证

设计登录认证,使用户必须先登录才能访问其他接口

我们新建一个ArticleController类进行测试

在这里插入图片描述

package com.example.Controller;

import com.example.Pojo.Result;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("article")
public class ArticleController {

    @GetMapping("list")
    public Result<String> list(){
        return Result.success("测式登录认证");
    }
}

试试在不等录的情况下能否访问

在这里插入图片描述

发现能访问,这是不可以的

所以,我们必须借助令牌接口,进行身份识别

令牌:一段数据,承载业务数据,减少后续请求查询数据库的次数,同时要防止篡改,保证信息的合法和有效性

JWT令牌

jwt定义了一种简洁,自身包含的格式,用于通信双方以json数据格式安全的传输信息;

1生成令牌

导入依赖

 <!--导入JWT依赖-->
        <dependency>
            <groupId>com.auth0</groupId>
            <artifactId>java-jwt</artifactId>
            <version>4.4.0</version>
        </dependency>

设置工具类JWTUtils

package com.example.Utils;

import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.interfaces.Claim;
import com.auth0.jwt.interfaces.DecodedJWT;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;

public class JWTUtil {
    private static final String KEY="horobi";

    public static String  getToken(Map<String,Object> claim) {

        //生成jwt的代码
        String token= JWT.create().
                withClaim("user",claim)//添加载荷
                .withExpiresAt(new Date(System.currentTimeMillis()+1000*60*60*12))//添加过期时间,当前时间后的1000*60*60*12毫秒
                .sign(Algorithm.HMAC256(KEY));//配置算法并指定密钥
        //System.out.println("这是token:\n"+token);
        return token;
    }


    public static Map<String, Object> parseToken(String token){
        //验证JWT
        //生成的token
        JWTVerifier horobi = JWT.require(Algorithm.HMAC256(KEY)).build();
        DecodedJWT verify = horobi.verify(token);//验证token,生成一个解析器
        Claim user = verify.getClaim("user");
        Map<String, Object> claim = user.asMap();

//        JWT.require(Algorithm.HMAC256(KEY))
//                .build()
//                .verify(token)
//                .getClaim("claims")
//                .asMap();
        //过期也会验证失败
        return  claim;
    }
}

2重写登录方法

在这里插入图片描述

 @PostMapping("login")
    public Result<String> login(@Pattern(regexp = "^\\S{5,16}$") String username,@Pattern(regexp = "^\\S{5,16}$")String password){
        //根据用户名查询用户
        User loginUser =userService.findByUserName(username);
        if(loginUser==null){
            return Result.error("用户名错误");
        }
        //判断密码是否正确 密码是密文
        if(MdUtil.getMDString(password).equals(loginUser.getPassword())){
            //登录成功
            Map<String,Object> claim=new HashMap<>();
            claim.put("id",loginUser.getId());
            claim.put("username",loginUser.getUsername());
            String token = JWTUtil.getToken(claim);
            return Result.success(token);
        }
        return Result.error("密码错误");
    }

用户在登录成功后,系统会自动下发JWT令牌,然后在后续的每次请求中,浏览器都需要请求header中携带到服务器端,请求头的名称为Authorization,值为登录时下发的JWT令牌,如果检查到用户为登录,则http响应为401(未授权)

3在ArticleController写验证token

在这里插入图片描述

@GetMapping("list")
    public Result<String> list(@RequestHeader(name="Authorization") String token, HttpServletResponse response){
        //验证token
        try{
            Map<String, Object> claim = JWTUtil.parseToken(token);
        }catch (Exception e){
            //http响应码为401
            response.setStatus(401);
            return Result.success("未登录");
        }

        return Result.success("测式登录认证");
    }

4验证

在这里插入图片描述

登录

在这里插入图片描述

再去

在这里插入图片描述

拦截器

设置一个拦截器,这样就不用在每个请求里面设置方法

新建Interceptors包,新建LoginInterceptor

package com.example.Interceptors;

import com.auth0.jwt.interfaces.Claim;
import com.example.Pojo.Result;
import com.example.Utils.JWTUtil;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;

import java.util.Map;

@Component//把拦截器放入IOC容器
public class LoginInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        //令牌验证
        String token = request.getHeader("Authorization");
        //验证token
        try{
            Map<String, Object> claim = JWTUtil.parseToken(token);
        }catch (Exception e){
            //http响应码为401
            response.setStatus(401);
            System.out.println("可能没有登录");
            return false;//不放行
        }
        return true;//放行
    }
}

新建Config包,新建WebConfig为配置类

package com.example.Config;

import com.example.Interceptors.LoginInterceptor;
import jakarta.annotation.Resource;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

public class WebConfig implements WebMvcConfigurer {

    @Resource
    private LoginInterceptor loginInterceptor;

    @Override
    public void addInterceptors(InterceptorRegistry registry) {//注册拦截器
        registry.addInterceptor(loginInterceptor)
                .excludePathPatterns("/user/login","/user/register")//登录接口和注册接口不拦截
    }
}

再修改ArticleController进行测试

在这里插入图片描述

在这里插入图片描述

  • 7
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

菜了再学

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值