在前面的文章里面介绍了相关的登录模块,在这里我们来具体实现下用户登录模块。
由于这里主要是演示项目,因此我们的登录模块就不做的很完善了,因此主要使用普通的方式进行登录,也就是登录之后,随机生成一个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、这里我们的密码使用加盐的方式进行验证,数据库存储的密码是不可逆的。
最后按照惯例,附上本案例的源码,登陆后即可下载。












还没有评论,来说两句吧...