在前面的文章里面介绍了相关的登录模块,在这里我们来具体实现下用户登录模块。
由于这里主要是演示项目,因此我们的登录模块就不做的很完善了,因此主要使用普通的方式进行登录,也就是登录之后,随机生成一个token,然后把token与userno用户编号存储到redis缓存中,后期所有的请求都在request-header里面传递进来一个token,这样就可以通用了。具体的实现如下。
一、创建一张用户表,并且插入一个用户
CREATE TABLE `user` ( `id` int(11) NOT NULL AUTO_INCREMENT, `username` varchar(45) DEFAULT NULL COMMENT '用户名', `no` varchar(8) DEFAULT NULL COMMENT '用户编号', `phone` varchar(11) DEFAULT NULL COMMENT '手机号码', `password` varchar(65) DEFAULT NULL COMMENT '密码', `salt` varchar(45) DEFAULT NULL COMMENT '密码加密盐', `head` varchar(45) DEFAULT NULL COMMENT '头像', `logincount` int(11) DEFAULT NULL COMMENT '登录次数', `registerdate` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '注册时间', `lastlogindate` datetime DEFAULT NULL COMMENT '最近一次登录时间', PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; INSERT INTO `test8`.`user`(`id`, `username`, `no`, `phone`, `password`, `salt`, `head`, `logincount`, `registerdate`, `lastlogindate`) VALUES (1, '张三', '64124152', '13888888888', '1748f7129ace488042e2c8e319ca7e2c', '1l2j3g', NULL, 0, '2023-10-31 10:50:47', NULL);
此时我们的数据库就完成了,示例图如下:
二、创建user-service模块
这里的话我们在前面的模板上创建一个user-service的模块
在这个模块里面我们编写一个登录和退出的接口,接口controller类示例如下:
package org.user.service.controller; import javax.validation.Valid; import org.common.model.http.BaseResponse; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestHeader; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import org.user.service.request.UserRequest; import org.user.service.service.UserService; /** * 用户登录与退出的逻辑 */ @RestController public class LoginController { @Autowired private UserService userService; @RequestMapping("/login") public BaseResponse login(@RequestBody @Valid UserRequest request) { return userService.checkUserExistByPhone(request.getPhone()); } @RequestMapping("/logout") public BaseResponse logout(@RequestHeader("token") String token) { return userService.logout(token); } }
登录和退出的具体逻辑示例代码如下:
package org.user.service.service.impl; import java.util.concurrent.TimeUnit; import org.common.model.constants.RedisPrefix; import org.common.model.exception.SeckillException; import org.common.model.http.BaseResponse; import org.common.model.http.HttpStatusCode; import org.common.model.utils.MD5Util; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.stereotype.Service; import org.user.service.dto.UserDTO; import org.user.service.mapper.UserDao; import org.user.service.response.UserResponse; import org.user.service.service.UserService; import com.alibaba.nacos.common.utils.UuidUtils; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.toolkit.StringUtils; import cn.hutool.core.bean.BeanUtil; @Service public class UserServiceImpl implements UserService { @Autowired private UserDao userDao; @Autowired private RedisTemplate<String, Object> redisTemplate; @Override public BaseResponse checkUserExistByPhone(String phone) { QueryWrapper<UserDTO> query = new QueryWrapper<UserDTO>(); query.eq("phone", phone); UserDTO user = userDao.selectOne(query); if (user == null) { throw new SeckillException(HttpStatusCode.USERNOTFOUND); } String pwd = user.getPassword(); String salt = user.getSalt(); String calcPass = MD5Util.formPassToDBPass(phone, salt); if (!StringUtils.equals(pwd, calcPass)) { throw new SeckillException(HttpStatusCode.PASSWORDERROR); } String token = UuidUtils.generateUuid().replaceAll("-", ""); redisTemplate.opsForValue().set(RedisPrefix.USERTOKEN + token, user.getNo(), 60 * 24 * 7, TimeUnit.MINUTES); UserResponse response = BeanUtil.copyProperties(user, UserResponse.class); response.setToken(token); return BaseResponse.ok(HttpStatusCode.SUCCESS, response); } @Override public BaseResponse logout(String token) { redisTemplate.delete(RedisPrefix.USERTOKEN + token); return BaseResponse.ok(); } }
到这里我们的核心代码就编写完成了,接着我们运行测试一下:
用户登录没有任何问题。
备注:
1、这里我们的登录比较简单,主要是为了演示。
2、这里的token放在redis缓存中,即使后端部署多个示例也不影响。
3、这里又一个common的项目,主要是一些公共的信息,可参考源码。
4、这里我们没有把用户的id给返回给前端,主要是由于我们这里的示例项目userid是数据库自增的,为了安全起见,避免被暴力脱库,所以我们使用用户编号no来获取数据。
5、这里我们的密码使用加盐的方式进行验证,数据库存储的密码是不可逆的。
最后按照惯例,附上本案例的源码,登陆后即可下载。
还没有评论,来说两句吧...