保姆级笔记:人脸智能识别系统(二)

第二天笔记

本章内容:完善后端代码,将验证码存入redis,同时完成登录接口

2.1进行redis配置

打开后端项目的application.yml
在这里插入图片描述

添加redis相关配置,最终application.yml内容如下:

spring:
  application:
    name: cv
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/community?useUnicode=true&characterEncoding=utf-8
    username: 'root'
    password: '!Aa711217720414'
    
  #新增代码
  redis:
    open: true
    database: 2  # 2号数据库
    host: localhost  #redis地址
    port: 6379  #redis端口
  #
server:
  port: 8083

2.2调用api操作redis

在LoginController.java中注入RedisTemplate:
在这里插入图片描述

@RestController
public class LoginController {

    @Autowired
    private RedisTemplate redisTemplate;//注入RedisTemplate

将生成的验证码存入redis:
在这里插入图片描述
直接运行项目后端,但后打开RedisDesktop查看数据:
向redis添加成功。
在这里插入图片描述

2.3完成登录逻辑

2.3.1找到前端逻辑

找到前端页面index.vue
在这里插入图片描述
找到登录按钮,找到相应的登录方法
在这里插入图片描述
跳转到方法相应的位置
在这里插入图片描述
在这里插入图片描述
然后跳转到store/modules/user.js里的login方法
在这里插入图片描述
发现里面调用了login()方法,因此再寻找根文件:
在这里插入图片描述
跳转到src/api/sys/user.js里的login方法
在这里插入图片描述
因此,后台登录接口的url为“/login”

2.3.2编写登录接口

登录接口使用post请求,因为是提交数据,且需要返回一个Token。
(即登录成功之后生成一个令牌,将令牌传到后端,该令牌就代表登录状态。因此每次操作时后端都需要去验证该令牌是否正确。若令牌正确,则可以进行操作。若令牌失效,则需要重新登录。)
接口文档:
在这里插入图片描述
根据API文档中的参数,建立form.LoginForm.java,表示输入的表单数据
在这里插入图片描述
LoginForm.java代码:

/**
 * 功能:
 * 作者:
 * 日期:2024-07-16 11:55
 */
package com.cas.form;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@AllArgsConstructor
@NoArgsConstructor
public class LoginForm {
	//每一属性与api文档中的参数部分相对应
    private String captcha;//登录表单中的验证码
    private String password;//登录表单中的密码
    private String username;//登录表单中的用户名
    private String uuid;//登录表单中的uuid
}

在LoginController中编写登录接口

@PostMapping("/login")
public Result login(@RequestBody LoginForm loginForm, HttpSession session){//该方法接收登录表单对象LoginForm,等同于前端目录中src/views/login/index.vue中handleLogin里的LoginForm对象。注意,由于前端传递的是json数据,因此需要采用@RequestBody将json格式转换为java对象                                                                //session表示当登录成功后,将当前用户存入session中。后端存入session,前端存入cookie


}

设计登录逻辑。由于登录时需要判断用户名、密码、验证码与用户状态,因此按顺序进行验证。在LoginController.java编写验证接口:

    //登录接口
    @PostMapping("/login")
    public Result login(@RequestBody LoginForm loginForm, HttpSession session){//该方法接收登录表单对象LoginForm,等同于前端目录中src/views/login/index.vue中handleLogin里的LoginForm对象。注意,由于前端传递的是json数据,因此需要采用@RequestBody将json格式转换为java对象
                                                                              //session表示当登录成功后,将当前用户存入session中。后端存入session,前端存入cookie
        //第一步:验证码校验
        //从Redis中获取验证码
        String code = (String)this.redisTemplate.opsForValue().get(loginForm.getUuid());
        //判断验证码是否有效
        if(code==null){//验证码为空,表示验证码失效
            return Result.ok().put("status","fail").put("data","验证码已过期");//ok()表示前后端已连通,code==null表示验证码失效
        }
        //判断验证码是否正确
        if(!code.equals(loginForm.getCaptcha())){//若验证码不匹配
            return Result.ok().put("status","fail").put("data","验证码错误");
        }

        //若验证码通过验证,则判断用户名是否正确,需要注入UserService
        QueryWrapper<User> queryWrapper=new QueryWrapper<>();
        queryWrapper.eq("username",loginForm.getUsername());//将数据库表中的username与输入的用户名进行比较
        User user=this.userService.getOne(queryWrapper);
        if(user==null){//如果没有输入用户名
            return Result.ok().put("status","fail").put("data","用户名不存在");
        }
        //若用户名正确,则判断密码是否正确
        String password= SecureUtil.sha256(loginForm.getPassword());//因为数据库的密码是经过加密之后的,所以输入密码之后也需要加密
        if(!password.equals(user.getPassword())){//若不相等,则密码错误。注意,该password是从数据库里面查出来的,因此要通过user调用
            return Result.ok().put("status","fail").put("data","密码错误");
        }
        //查看用户状态,是否被锁定
        if(user.getStatus()==0){//此时用户被锁定
            return Result.ok().put("status","fail").put("data","当前用户被锁定");
        }
        //若全部验证通过,则登录成功,将user存入session中
        session.setAttribute("user",user);
        return Result.ok().put("status","success");
    }

登录成功以后,需要创建Token并对Token进行验证,因此在application.yml中添加如下配置,设置jwt的相关参数:

jwt:
  secret: MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4K67DMlSPXbgG0MPp0gH # jwt密钥
  expire: 86400000 # jwt生存时间
  #  expire: 10000
  subject: door # jwt标题

在utils文件夹中导入JwtUtil.java
在这里插入图片描述
JwtUtil.java代码:

package com.cas.utils;

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jws;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import java.util.Date;
import java.util.UUID;

@ConfigurationProperties(prefix = "jwt") //在配置文件中找到前缀为"jwt”的属性
@Component
public class JwtUtil {
    private long expire;
    private String secret;
    private String subject;

    /**
     * 生成token
     *
     * @param userId
     * @return
     */
    public String createToken(String userId) {
        String token = Jwts.builder()
                //载荷:自定义信息
                .claim("userId", userId)
                //载荷:默认信息
                .setSubject(subject) //令牌主题
                .setExpiration(new Date(System.currentTimeMillis() + expire)) //过期时间
                .setId(UUID.randomUUID().toString())
                //签名哈希
                .signWith(SignatureAlgorithm.HS256, secret)
                //组装jwt字符串
                .compact();
        return token;
    }

    public boolean checkToken(String token){
        if(StringUtils.isEmpty(token)){
            return false;
        }
        try {
            Jws<Claims> claimsJws = Jwts.parser().setSigningKey(secret).parseClaimsJws(token);
        } catch (Exception e) {
            return false;
        }
        return true;
    }

    public long getExpire() {
        return expire;
    }

    public void setExpire(long expire) {
        this.expire = expire;
    }

    public String getSecret() {
        return secret;
    }

    public void setSecret(String secret) {
        this.secret = secret;
    }

    public String getSubject() {
        return subject;
    }

    public void setSubject(String subject) {
        this.subject = subject;
    }
}

然后在LoginController.java中添加jwt验证过程,首先注入JwtUtil:
在这里插入图片描述

然后在LoginController.java的登录接口中追加token建立与验证过程。完整的登录接口如下:

    //登录接口
    @PostMapping("/login")
    public Result login(@RequestBody LoginForm loginForm, HttpSession session){//该方法接收登录表单对象LoginForm,等同于前端目录中src/views/login/index.vue中handleLogin里的LoginForm对象。注意,由于前端传递的是json数据,因此需要采用@RequestBody将json格式转换为java对象
                                                                              //session表示当登录成功后,将当前用户存入session中。后端存入session,前端存入cookie
        //第一步:验证码校验
        //从Redis中获取验证码
        String code = (String)this.redisTemplate.opsForValue().get(loginForm.getUuid());
        //判断验证码是否有效
        if(code==null){//验证码为空,表示验证码失效
            return Result.ok().put("status","fail").put("data","验证码已过期");//ok()表示前后端已连通,code==null表示验证码失效
        }
        //判断验证码是否正确
        if(!code.equals(loginForm.getCaptcha())){//若验证码不匹配
            return Result.ok().put("status","fail").put("data","验证码错误");
        }

        //若验证码通过验证,则判断用户名是否正确,需要注入UserService
        QueryWrapper<User> queryWrapper=new QueryWrapper<>();
        queryWrapper.eq("username",loginForm.getUsername());//将数据库表中的username与输入的用户名进行比较
        User user=this.userService.getOne(queryWrapper);
        if(user==null){//如果没有输入用户名
            return Result.ok().put("status","fail").put("data","用户名不存在");
        }
        //若用户名正确,则判断密码是否正确
        String password= SecureUtil.sha256(loginForm.getPassword());//因为数据库的密码是经过加密之后的,所以输入密码之后也需要加密
        if(!password.equals(user.getPassword())){//若不相等,则密码错误。注意,该password是从数据库里面查出来的,因此要通过user调用
            return Result.ok().put("status","fail").put("data","密码错误");
        }
        //查看用户状态,是否被锁定
        if(user.getStatus()==0){//此时用户被锁定
            return Result.ok().put("status","fail").put("data","当前用户被锁定");
        }
        //若全部验证通过,则登录成功,将user存入session中
        session.setAttribute("user",user);

        //登录成功以后,需要创建token,使用工具类jwt
        String token=this.jwtUtil.createToken(String.valueOf(user.getUserId()));
        //将创建好的token存入redis
        redisTemplate.opsForValue().set("user-"+user.getUserId(),token,jwtUtil.getExpire());
        //将token与有效期进行返回
        Map<String,Object> map=new HashMap<>();
        map.put("token",token);//token值
        map.put("expire",jwtUtil.getExpire());//有效日期
        return Result.ok().put("status","success").put("data",map);
    }
  • 5
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

YZ122552

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

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

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

打赏作者

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

抵扣说明:

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

余额充值