尚融宝20-实现用户注册和用户认证

这篇具有很好参考价值的文章主要介绍了尚融宝20-实现用户注册和用户认证。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

目录

一、需求

二、前端整合发送验证码

三、实现用户注册

1、创建VO对象

2、定义常量

3、引入MD5工具类

4、Controller

5、Service

6、前端整合

四、实现用户登录

1、后端整合JWT

2、前端整合

五、校验用户登录

1、后端

2、前端


一、需求

尚融宝20-实现用户注册和用户认证

 尚融宝20-实现用户注册和用户认证

二、前端整合发送验证码

点击获取验证码后先对手机号进行验证是否为空,其次禁用发送验证码按钮防止重复提交,然后显示倒计时,调用后端的阿里云微服务发送验证码,下面这篇文章提到如何整合阿里云短信微服务整合阿里云短信服务https://blog.csdn.net/m0_62946761/article/details/129625885?spm=1001.2014.3001.5501

methods: {
    //发短信  
    send() {
      if (!this.userInfo.mobile) {
        this.$message.error('请输入手机号')
        return
      }

      //防止重复提交
      if (this.sending) return
      this.sending = true

      //倒计时
      this.timeDown()

      //远程调用发送短信的接口
      this.$axios
        .$get('/api/sms/send/' + this.userInfo.mobile)
        .then((response) => {
          this.$message.success(response.message)
        })
    },

    //倒计时
    timeDown() {
      console.log('进入倒计时')
      this.leftSecond = this.second
      //创建定时器
      const timmer = setInterval(() => {
        //计数器减一
        this.leftSecond--
        if (this.leftSecond <= 0) {
          //停止定时器
          clearInterval(timmer)
          //还原计数器
          this.leftSecond = this.second
          //还原按钮状态
          this.sending = false
        }
      }, 1000)
    },
  },

三、实现用户注册

1、创建VO对象

service-core中创建vo(value object),根据表单创建出来的对象,这里其实可以用复用原本的userInfo对象,它已经包含了这些属性

@Data
@ApiModel(description="注册对象")
public class RegisterVO {

    @ApiModelProperty(value = "用户类型")
    private Integer userType;

    @ApiModelProperty(value = "手机号")
    private String mobile;

    @ApiModelProperty(value = "验证码")
    private String code;

    @ApiModelProperty(value = "密码")
    private String password;
}

2、定义常量

UserInfo中添加常量

public static final Integer STATUS_NORMAL = 1;
public static final Integer STATUS_LOCKED = 0;

3、引入MD5工具类

guigu-common中util包,引入工具类:

MD5.java:MD5加密,对用户密码加密后再存入数据库

4、Controller

先对手机,密码,验证码进行校验判断,最后再调用service的注册方法

@Api(tags = "会员接口")
@RestController
@RequestMapping("/api/core/userInfo")
@Slf4j
@CrossOrigin
public class UserInfoController {

    @Resource
    private UserInfoService userInfoService;

    @Resource
    private RedisTemplate redisTemplate;

    @ApiOperation("会员注册")
    @PostMapping("/register")
    public R register(@RequestBody RegisterVO registerVO){

        String mobile = registerVO.getMobile();
        String password = registerVO.getPassword();
        String code = registerVO.getCode();

        //MOBILE_NULL_ERROR(-202, "手机号不能为空"),
        Assert.notEmpty(mobile, ResponseEnum.MOBILE_NULL_ERROR);
        //MOBILE_ERROR(-203, "手机号不正确"),
        Assert.isTrue(RegexValidateUtils.checkCellphone(mobile), ResponseEnum.MOBILE_ERROR);
        //PASSWORD_NULL_ERROR(-204, "密码不能为空"),
        Assert.notEmpty(password, ResponseEnum.PASSWORD_NULL_ERROR);
        //CODE_NULL_ERROR(-205, "验证码不能为空"),
        Assert.notEmpty(code, ResponseEnum.CODE_NULL_ERROR);

        //校验验证码
        String codeGen = (String)redisTemplate.opsForValue().get("srb:sms:code:" + mobile);
        //CODE_ERROR(-206, "验证码不正确"),
        Assert.equals(code, codeGen, ResponseEnum.CODE_ERROR);

        //注册
        userInfoService.register(registerVO);
        return R.ok().message("注册成功");
    }
}

5、Service

接口:UserInfoService

public interface UserInfoService extends IService<UserInfo> {

    void register(RegisterVO registerVO);
}

实现:UserInfoServiceImpl

先判断用户表是否已经注册过该用户,如果没有就插入用户信息表和用户账户表,新建账户0块钱,这里涉及两张表的操作,在类上加上事务回滚

@Service
public class UserInfoServiceImpl extends ServiceImpl<UserInfoMapper, UserInfo> implements UserInfoService {

    @Resource
    private UserAccountMapper userAccountMapper;

    @Transactional(rollbackFor = {Exception.class})
    @Override
    public void register(RegisterVO registerVO) {

        //判断用户是否被注册
        QueryWrapper<UserInfo> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("mobile", registerVO.getMobile());
        Integer count = baseMapper.selectCount(queryWrapper);
        //MOBILE_EXIST_ERROR(-207, "手机号已被注册"),
        Assert.isTrue(count == 0, ResponseEnum.MOBILE_EXIST_ERROR);

        //插入用户基本信息
        UserInfo userInfo = new UserInfo();
        userInfo.setUserType(registerVO.getUserType());
        userInfo.setNickName(registerVO.getMobile());
        userInfo.setName(registerVO.getMobile());
        userInfo.setMobile(registerVO.getMobile());
        userInfo.setPassword(MD5.encrypt(registerVO.getPassword()));
        userInfo.setStatus(UserInfo.STATUS_NORMAL); //正常
        //设置一张静态资源服务器上的头像图片
        userInfo.setHeadImg("https://srb-file.oss-cn-beijing.aliyuncs.com/avatar/07.jpg");
        baseMapper.insert(userInfo);

        //创建会员账户
        UserAccount userAccount = new UserAccount();
        userAccount.setUserId(userInfo.getId());
        userAccountMapper.insert(userAccount);
    }
}

6、前端整合

pages/register.vue

//注册
register() {
  this.$axios
    .$post('/api/core/userInfo/register', this.userInfo)
    .then((response) => {
      this.step = 2
    })
},

四、实现用户登录

1、后端整合JWT

尚融宝20-实现用户注册和用户认证

这里使用JWT令牌来校验用户的登录,下面这篇文章讲解了JWT令牌尚融宝18-JWT令牌和测试_zoeil的博客-CSDN博客https://blog.csdn.net/m0_62946761/article/details/129962876?spm=1001.2014.3001.5502&ydreferer=aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L20wXzYyOTQ2NzYxP3R5cGU9YmxvZw%3D%3D

导入依赖

<dependency>
    <groupId>io.jsonwebtoken</groupId>
    <artifactId>jjwt</artifactId>
</dependency>

JWT工具

service-base中添加util包

添加JwtUtils类,包括生成token,校验token等主要功能

public class JwtUtils {

    private static long tokenExpiration = 24*60*60*1000;
    private static String tokenSignKey = "A1t2g3uigu123456";

    private static Key getKeyInstance(){
        SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256;
        byte[] bytes = DatatypeConverter.parseBase64Binary(tokenSignKey);
        return new SecretKeySpec(bytes,signatureAlgorithm.getJcaName());
    }

    public static String createToken(Long userId, String userName) {
        String token = Jwts.builder()
                .setSubject("SRB-USER")
                .setExpiration(new Date(System.currentTimeMillis() + tokenExpiration))
                .claim("userId", userId)
                .claim("userName", userName)
                .signWith(SignatureAlgorithm.HS512, getKeyInstance())
                .compressWith(CompressionCodecs.GZIP)
                .compact();
        return token;
    }

    /**
     * 判断token是否有效
     * @param token
     * @return
     */
    public static boolean checkToken(String token) {
        if(StringUtils.isEmpty(token)) {
            return false;
        }
        try {
            Jwts.parser().setSigningKey(getKeyInstance()).parseClaimsJws(token);
            return true;
        } catch (Exception e) {
            return false;
        }
    }


    public static Long getUserId(String token) {
        Claims claims = getClaims(token);
        Integer userId = (Integer)claims.get("userId");
        return userId.longValue();
    }

    public static String getUserName(String token) {
        Claims claims = getClaims(token);
        return (String)claims.get("userName");
    }

    public static void removeToken(String token) {
        //jwttoken无需删除,客户端扔掉即可。
    }

    /**
     * 校验token并返回Claims
     * @param token
     * @return
     */
    private static Claims getClaims(String token) {
        if(StringUtils.isEmpty(token)) {
            // LOGIN_AUTH_ERROR(-211, "未登录"),
            throw new BusinessException(ResponseEnum.LOGIN_AUTH_ERROR);
        }
        try {
            Jws<Claims> claimsJws = Jwts.parser().setSigningKey(getKeyInstance()).parseClaimsJws(token);
            Claims claims = claimsJws.getBody();
            return claims;
        } catch (Exception e) {
            throw new BusinessException(ResponseEnum.LOGIN_AUTH_ERROR);
        }
    }
}

创建VO对象

service-core中创建登录对象

@Data
@ApiModel(description="登录对象")
public class LoginVO {
    
    @ApiModelProperty(value = "用户类型")
    private Integer userType;

    @ApiModelProperty(value = "手机号")
    private String mobile;

    @ApiModelProperty(value = "密码")
    private String password;
}

用户信息对象

@Data
@ApiModel(description="用户信息对象")
public class UserInfoVO {

    @ApiModelProperty(value = "用户姓名")
    private String name;

    @ApiModelProperty(value = "用户昵称")
    private String nickName;
    
    @ApiModelProperty(value = "头像")
    private String headImg;
    
    @ApiModelProperty(value = "手机号")
    private String mobile;

    @ApiModelProperty(value = "1:出借人 2:借款人")
    private Integer userType;

    @ApiModelProperty(value = "JWT访问令牌")
    private String token;
}

UserInfoController,返回给前端用户信息对象供展示用

@ApiOperation("会员登录")
@PostMapping("/login")
public R login(@RequestBody LoginVO loginVO, HttpServletRequest request) {

    String mobile = loginVO.getMobile();
    String password = loginVO.getPassword();
    Assert.notEmpty(mobile, ResponseEnum.MOBILE_NULL_ERROR);
    Assert.notEmpty(password, ResponseEnum.PASSWORD_NULL_ERROR);

    String ip = request.getRemoteAddr();
    UserInfoVO userInfoVO = userInfoService.login(loginVO, ip);

    return R.ok().data("userInfo", userInfoVO);
}

接口:UserInfoService

UserInfoVO login(LoginVO loginVO, String ip);

实现:UserInfoServiceImpl

@Resource
private UserLoginRecordMapper userLoginRecordMapper;

@Transactional( rollbackFor = {Exception.class})
@Override
public UserInfoVO login(LoginVO loginVO, String ip) {
    String mobile = loginVO.getMobile();
    String password = loginVO.getPassword();
    Integer userType = loginVO.getUserType();

    //获取会员
    QueryWrapper<UserInfo> queryWrapper = new QueryWrapper<>();
    queryWrapper.eq("mobile", mobile);
    queryWrapper.eq("user_type", userType);
    UserInfo userInfo = baseMapper.selectOne(queryWrapper);

    //用户不存在
    //LOGIN_MOBILE_ERROR(-208, "用户不存在"),
    Assert.notNull(userInfo, ResponseEnum.LOGIN_MOBILE_ERROR);

    //校验密码
    //LOGIN_PASSWORD_ERROR(-209, "密码不正确"),
    Assert.equals(MD5.encrypt(password), userInfo.getPassword(), ResponseEnum.LOGIN_PASSWORD_ERROR);

    //用户是否被禁用
    //LOGIN_DISABLED_ERROR(-210, "用户已被禁用"),
    Assert.equals(userInfo.getStatus(), UserInfo.STATUS_NORMAL, ResponseEnum.LOGIN_LOKED_ERROR);

    //记录登录日志
    UserLoginRecord userLoginRecord = new UserLoginRecord();
    userLoginRecord.setUserId(userInfo.getId());
    userLoginRecord.setIp(ip);
    userLoginRecordMapper.insert(userLoginRecord);

    //生成token
    String token = JwtUtils.createToken(userInfo.getId(), userInfo.getName());
    UserInfoVO userInfoVO = new UserInfoVO();
    userInfoVO.setToken(token);
    userInfoVO.setName(userInfo.getName());
    userInfoVO.setNickName(userInfo.getNickName());
    userInfoVO.setHeadImg(userInfo.getHeadImg());
    userInfoVO.setMobile(userInfo.getMobile());
    userInfoVO.setUserType(userType);

    return userInfoVO;
}

2、前端整合

登录脚本pages/login.vue,按下登录按钮后请求后台获取用户信息对象,跳转到主页

methods: {
    //登录
    login() {
      this.$axios
        .$post('/api/core/userInfo/login', this.userInfo)
        .then((response) => {
          // 把用户信息存在cookie中
          cookie.set('userInfo', response.data.userInfo)
          window.location.href = '/user'
        })
    },
},

登陆后,免费注册这里需要换成用户的电话以证明登录 

尚融宝20-实现用户注册和用户认证

页面头信息 

components/AppHeader.vue

脚本

<script>
import cookie from 'js-cookie'

export default {
  data() {
    return {
      userInfo: null,
    }
  },

  mounted() {
    this.showInfo()
  },

  methods: {
    //显示用户信息  
    showInfo() {
      // debugger
      let userInfo = cookie.get('userInfo')
      if (!userInfo) {
        console.log('cookie不存在')
        this.userInfo = null
        return
      }  
      userInfo = JSON.parse(userInfo)  
      this.userInfo = userInfo
    },

    //退出  
    logout() {
      cookie.set('userInfo', '')
      //跳转页面
      window.location.href = '/login'
    },
  },
}
</script>

五、校验用户登录

1、后端

显示用户信息时需要先进行token的校验,service-core 中 UserInfoController添加令牌校验接口

@ApiOperation("校验令牌")
@GetMapping("/checkToken")
public R checkToken(HttpServletRequest request) {

    String token = request.getHeader("token");
    boolean result = JwtUtils.checkToken(token);

    if(result){
        return R.ok();
    }else{
        //LOGIN_AUTH_ERROR(-211, "未登录"),
        return R.setResult(ResponseEnum.LOGIN_AUTH_ERROR);
    }
}

这里我们原本测试使用的是基本的swagger2无法在请求头中添加token字段,可以使用postman,也可以使用民间加强版的swagger2,只需要以下几个步骤:

step1:service-base导入以下依赖

<dependency>
    <groupId>com.github.xiaoymin</groupId>
    <artifactId>swagger-bootstrap-ui</artifactId>
    <version>1.9.2</version>
</dependency>

step2:访问

http://localhost:8110/doc.html

step3:添加全局参数

尚融宝20-实现用户注册和用户认证

尚融宝20-实现用户注册和用户认证

2、前端

对于原本的显示用户信息的函数showInfo我们需要优化一下,在拿到cookie中的用户信息后,先请求后端服务器校验token,成功才显示信息

showInfo() {
    // debugger
    let userInfo = cookie.get('userInfo')

    if (!userInfo) {
        console.log('cookie不存在')
        this.userInfo = null
        return
    }

    userInfo = JSON.parse(userInfo)
    
    //先在服务器端校验token
    this.$axios({
        url: '/api/core/userInfo/checkToken',
        method: 'get',
        headers: {
            //如果token校验成功,再展示user信息
            token: userInfo.token,
        },
    }).then((response) => {
        console.log('校验成功')
        this.userInfo = userInfo
    })
},

可能你会有疑问为什么上面拿到响应数据进入then就代表着成功,因为axios响应拦截器中已经帮我们处理了未登录的情况文章来源地址https://www.toymoban.com/news/detail-420028.html

$axios.onResponse((response) => {
    console.log('Reciving resposne', response)
    if (response.data.code === 0) {
      return response         // 后端对于未登录的情况返回的状态码为-211
    } else if (response.data.code === -211) {
      console.log('token校验失败')
      cookie.set('userInfo', '')
      //debugger
      //跳转到登录页面
      window.location.href = '/login'
    } else {
      Message({
        message: response.data.message,
        type: 'error',
        duration: 5 * 1000,
      })
      return Promise.reject(response)
    }
  })

到了这里,关于尚融宝20-实现用户注册和用户认证的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • HTML实现用户注册页面

    效果图: 编写代码的时候用到了大量的正则表达式,大家可以去主页里找一下,里面有一篇就是关于常用正则表达式的介绍。

    2024年02月11日
    浏览(36)
  • Java开发:实现用户注册登录的功能

    一、前言 在Java开发过程中,实现用户的注册功能是最基本的,用户通过手机号或者邮箱作为注册账号也是非常常见的操作方式,不管是通过手机号注册或者邮箱注册,原理都差不多,那么本文就来分享一下在Java开发过程中的用户注册账号的功能实现。 二、准备工作 1、通过

    2023年04月09日
    浏览(47)
  • SpringBoot整合邮箱验证码实现用户注册

    唠嗑部分 今天我们来分享一下在系统开发过程中,如何使用验证码来验证用户并完成用户注册 首先来看一下成品界面展示 说一下以上注册功能的设计: 用户手动输入用户名(全数据库唯一)、密码、确认密码、邮箱地址(单个邮箱最多可注册3个用户)、正确的邮箱验证码,即可

    2024年02月08日
    浏览(60)
  • 尚融宝25-投资列表展示以及实现充值功能

    目录 一、展示投资列表 (一)需求 (二)后端 (三)前端 二、充值功能 (一)需求 1、需求描述 2、流程 (二)充值 1、后端 2、前端 (三)回调接口 1、定义回调接口 2、增加交易流水 (四)接口调用幂等性 1、接口幂等性原则 2、解决方案 标的形成后,客户可在客户端

    2024年02月06日
    浏览(40)
  • 用前端框架Bootstrap和Django实现用户注册页面

    命令如下: 执行下面条命令依次创建需要的应用: 名叫users的应用创建好后,还需要在全局配置文件中对应在用进行注册,具体方法如下: 打开““E:Python_projectP_001myshop-testmall_backendmall_backendsettings.py””文件,找到名叫“INSTALLED_APPS”的列表(list),在其中加入应用名,

    2024年02月06日
    浏览(51)
  • MVC框架实现用户登录注册功能(连接数据库)

    一、简单理解MVC框架 二、项目结构 三、项目源码 3.1 User 3.2 UserDao 3.3 RegisterDao 3.4 servletControll 3.5 servletControllRegister 3.6 web.xml 3.7 login.jsp 3.8 register.jsp 3.9 success.jsp 3.10 failure.jsp  四、实现效果 总结 本篇文章主要介绍利用MVC框架去实现一个简单的用户登录注册功能,内容主

    2024年02月06日
    浏览(57)
  • 使用Django Rest Framework设计与实现用户注册API

    在现代Web应用开发中,RESTful API已成为前后端分离架构中的关键组件。Django Rest Framework (DRF) 是一款基于Django的优秀库,提供了丰富的工具和接口,极大地简化了RESTful API的设计与实现。本文将以用户注册功能为例,展示如何运用DRF构建一个完整的API端点,包括数据验证、模型

    2024年04月25日
    浏览(32)
  • 用Java代码实现学生管理系统(可实现用户登录注册功能)

    简单实现学生系统的登录和注册,以及学生信息添加、删除,修改、查询功能。根据需求,创建一个学生类和和用户类以及学生系统类,在登录管理系统之前需要先注册用户,只有输入正确的用户名和密码才可以登录,忘记密码后可以根据用户信息进行修改,用容器存储学生

    2024年02月05日
    浏览(44)
  • Django实现用户注册登录,表单提交后跳转网页(学习笔记)

    效果图如下:   使用命令提示符,进入想存放项目的目录: 在项目coco目录下新建static文件夹,用于存放网页文件的css,js,imgs 在coco_app目录下新建文件夹templates,用于存放需要用到的HTML网页 打开coco文件夹中的settings.py注册coco_app 引用templates 连接数据库,这里我用的MySQL数据

    2023年04月11日
    浏览(80)
  • Javaweb程序设计基础入门eclipse实现用户注册登录和session存储

    通过HTML,CSS,JavaScript和JSP实现页面的注册,登录和信息显示的三个界面的设计。 1.1注册界面 2.登录界面 3.通过Java代码进行登录界面的校验 1.用request.getParameter()获取表单提交的数据来存储账号和密码 2.if语句来进行账号和密码的校验 4.信息显示界面HTML 通过requst.getParameter()获

    2024年02月05日
    浏览(39)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包