Feat: [后台]:完成注册,登录,获取验证码接口

This commit is contained in:
fanxb 2019-07-06 17:38:59 +08:00
parent 41532ef476
commit ae652e9c08
14 changed files with 334 additions and 20 deletions

View File

@ -9,7 +9,7 @@
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>business</artifactId>
<artifactId>bookmark-business</artifactId>
<packaging>pom</packaging>
<modules>
<module>user</module>
@ -18,7 +18,7 @@
<dependencies>
<dependency>
<groupId>com.fanxb</groupId>
<artifactId>common</artifactId>
<artifactId>bookmark-common</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>

View File

@ -3,13 +3,13 @@
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>business</artifactId>
<artifactId>bookmark-business</artifactId>
<groupId>com.fanxb</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>user</artifactId>
<artifactId>bookmark-business-user</artifactId>
</project>

View File

@ -1,8 +1,13 @@
package com.fanxb.bookmark.business.user.controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.fanxb.bookmark.business.user.entity.LoginBody;
import com.fanxb.bookmark.business.user.entity.RegisterBody;
import com.fanxb.bookmark.business.user.service.UserService;
import com.fanxb.bookmark.common.entity.Result;
import com.fanxb.bookmark.common.entity.User;
import org.apache.ibatis.annotations.Param;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
/**
* 类功能简述
@ -15,8 +20,48 @@ import org.springframework.web.bind.annotation.RestController;
@RequestMapping("/user")
public class UserController {
@GetMapping("/test")
public String test() {
return "abce";
@Autowired
private UserService userService;
/**
* Description: 注册用户
*
* @param body 注册表单
* @return com.fanxb.bookmark.common.entity.Result
* @author fanxb
* @date 2019/7/6 16:34
*/
@PutMapping("")
public Result register(@RequestBody RegisterBody body) {
userService.register(body);
return Result.success(null);
}
/**
* Description: 用户登录
*
* @param user 登录表单
* @return com.fanxb.bookmark.common.entity.Result
* @author fanxb
* @date 2019/7/6 16:35
*/
@PostMapping("/login")
public Result login(@RequestBody LoginBody body) {
return Result.success(userService.login(body));
}
/**
* Description: 获取验证码
*
* @param email 邮箱
* @return com.fanxb.bookmark.common.entity.Result
* @author fanxb
* @date 2019/7/5 17:37
*/
@GetMapping("/authCode")
public Result getAuthCode(@Param("email") String email) {
userService.sendAuthCode(email);
return Result.success(null);
}
}

View File

@ -1,5 +1,9 @@
package com.fanxb.bookmark.business.user.dao;
import com.fanxb.bookmark.common.entity.User;
import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Component;
/**
* 类功能简述
* 类功能详述
@ -7,5 +11,35 @@ package com.fanxb.bookmark.business.user.dao;
* @author fanxb
* @date 2019/7/6 11:36
*/
public class UserDao {
@Component
public interface UserDao {
/**
* Description: 新增一个用户
*
* @param user user
* @author fanxb
* @date 2019/7/6 11:37
*/
void addOne(User user);
/**
* Description: 通过用户名或者email获取用户信息
*
* @param str username/email
* @return com.fanxb.bookmark.common.entity.User
* @author fanxb
* @date 2019/7/6 16:45
*/
User selectByUsernameOrEmail(String str);
/**
* Description: 更新用户上次登录时间
*
* @param time 时间
* @param userId 用户id
* @author fanxb
* @date 2019/7/6 16:46
*/
void updateLastLoginTime(@Param("time") long time, @Param("userId") int userId);
}

View File

@ -1,11 +1,20 @@
package com.fanxb.bookmark.business.user.entity;
import lombok.Data;
/**
* 类功能简述
* 类功能简述登录表单
* 类功能详述
*
* @author fanxb
* @date 2019/7/6 17:25
*/
@Data
public class LoginBody {
/**
* 用户名或邮箱
*/
private String str;
private String password;
private boolean rememberMe;
}

View File

@ -1,11 +1,20 @@
package com.fanxb.bookmark.business.user.entity;
import lombok.Data;
/**
* 类功能简述
* 类功能简述登录返回数据
* 类功能详述
*
* @author fanxb
* @date 2019/7/6 16:52
*/
@Data
public class LoginRes {
private String token;
private int userId;
private String username;
private String email;
private String lastLoginTime;
private String icon;
}

View File

@ -1,11 +1,18 @@
package com.fanxb.bookmark.business.user.entity;
import lombok.Data;
/**
* 类功能简述
* 类功能简述 注册表单
* 类功能详述
*
* @author fanxb
* @date 2019/7/6 11:23
*/
@Data
public class RegisterBody {
private String username;
private String password;
private String email;
private String authCode;
}

View File

@ -0,0 +1,116 @@
package com.fanxb.bookmark.business.user.service;
import com.fanxb.bookmark.business.user.dao.UserDao;
import com.fanxb.bookmark.business.user.entity.LoginBody;
import com.fanxb.bookmark.business.user.entity.LoginRes;
import com.fanxb.bookmark.business.user.entity.RegisterBody;
import com.fanxb.bookmark.common.Constant;
import com.fanxb.bookmark.common.entity.MailInfo;
import com.fanxb.bookmark.common.entity.User;
import com.fanxb.bookmark.common.exception.CustomException;
import com.fanxb.bookmark.common.exception.FormDataException;
import com.fanxb.bookmark.common.util.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.HashMap;
import java.util.Map;
/**
* 类功能简述
* 类功能详述
*
* @author fanxb
* @date 2019/7/5 17:39
*/
@Service
public class UserService {
private static final String DEFAULT_ICON = "defaultIcon.png";
/**
* 短期jwt失效时间
*/
private static final long SHORT_EXPIRE_TIME = 2 * 60 * 60 * 1000;
/**
* 长期jwt失效时间
*/
private static final long LONG_EXPIRE_TIME = 30 * TimeUtil.DAY_MS;
@Autowired
private UserDao userDao;
/**
* Description: 向目标发送验证码
*
* @param email 目标
* @author fanxb
* @date 2019/7/5 17:48
*/
public void sendAuthCode(String email) {
MailInfo info = new MailInfo();
info.setSubject("签签世界注册验证码");
int code = StringUtil.getRandomNumber(6, 6);
info.setContent("欢迎注册 签签世界 ,本次验证码");
info.setContent(code + " 是您的验证码注意验证码有效期为15分钟哦");
info.setReceiver(email);
if (Constant.isDev) {
code = 123456;
} else {
MailUtil.sendTextMail(info);
}
RedisUtil.set(Constant.authCodeKey(email), String.valueOf(code), Constant.AUTH_CODE_EXPIRE);
}
/**
* Description: 用户注册
*
* @param body 注册表单
* @author fanxb
* @date 2019/7/6 11:30
*/
public void register(RegisterBody body) {
String codeKey = Constant.authCodeKey(body.getEmail());
String realCode = RedisUtil.get(codeKey, String.class);
if ((!StringUtil.isEmpty(realCode)) && (!realCode.equals(body.getAuthCode()))) {
throw new CustomException("验证码错误");
}
RedisUtil.delete(codeKey);
User user = new User();
user.setUsername(body.getUsername());
user.setEmail(body.getEmail());
user.setIcon(DEFAULT_ICON);
user.setPassword(HashUtil.sha1(HashUtil.md5(body.getPassword())));
user.setCreateTime(System.currentTimeMillis());
user.setLastLoginTime(0);
userDao.addOne(user);
}
/**
* Description: 登录
*
* @param body 登录表单
* @return LoginRes
* @author fanxb
* @date 2019/7/6 16:37
*/
public LoginRes login(LoginBody body) {
User userInfo = userDao.selectByUsernameOrEmail(body.getStr());
if (userInfo == null) {
throw new FormDataException("账号/密码错误");
}
if (!HashUtil.sha1(HashUtil.md5(body.getPassword())).equals(userInfo.getPassword())) {
throw new FormDataException("账号/密码错误");
}
Map<String, String> data = new HashMap<>(1);
data.put("userId", String.valueOf(userInfo.getUserId()));
String token = JwtUtil.encode(data, Constant.jwtSecret, body.isRememberMe() ? LONG_EXPIRE_TIME : SHORT_EXPIRE_TIME);
LoginRes res = new LoginRes();
res.setToken(token);
res.setUserId(userInfo.getUserId());
res.setUsername(userInfo.getUsername());
res.setEmail(userInfo.getEmail());
res.setIcon(userInfo.getIcon());
userDao.updateLastLoginTime(System.currentTimeMillis(), userInfo.getUserId());
return res;
}
}

View File

@ -0,0 +1,31 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.fanxb.bookmark.business.user.dao.UserDao">
<insert id="addOne">
insert into user (username, email, icon, password, createTime, lastLoginTime)
value
(#{username}, #{email}, #{icon}, #{password}, #{createTime}, #{lastLoginTime})
</insert>
<select id="selectByUsernameOrEmail" resultType="com.fanxb.bookmark.common.entity.User">
select
userId,
username,
email,
icon,
password,
createTime
from user
where username = #{str} or email = #{str}
</select>
<update id="updateLastLoginTime">
update user
set lastLoginTime = #{time}
where userId= #{userId}
</update>
</mapper>

View File

@ -9,7 +9,7 @@
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>web</artifactId>
<artifactId>bookmark-web</artifactId>
<dependencies>
<dependency>
@ -18,7 +18,7 @@
</dependency>
<dependency>
<groupId>com.fanxb</groupId>
<artifactId>user</artifactId>
<artifactId>bookmark-business-user</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
</dependencies>

View File

@ -1,6 +1,7 @@
package com.fanxb.bookmark.web;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@ -12,6 +13,7 @@ import org.springframework.boot.autoconfigure.SpringBootApplication;
* @date 2019/7/4 19:38
*/
@SpringBootApplication(scanBasePackages = "com.fanxb.bookmark")
@MapperScan(basePackages = "com.fanxb.bookmark.**.dao")
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);

View File

@ -0,0 +1,12 @@
spring:
redis:
host: 192.168.64.129
port: 6380
datasource:
druid:
url: jdbc:mysql://192.168.64.129:3307/bookmark?useUnicode=true&characterEncoding=utf-8&useSSL=false&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTC
mail:
host: heiout.tapme.top
username: bookmark@mail.tapme.top
password: abcdefg123456
port: 587

View File

@ -1,9 +1,43 @@
isDev: true
jwtSecret: abcdefgh
server:
port: 8088
servlet:
context-path: /bookmark/api/
spring:
profiles:
active: dev
application:
name: bookmark
flyway:
baseline-on-migrate: true
cache:
type: redis
redis:
database: 0
host: localhost
password:
timeout: 500ms
lettuce:
pool:
max-active: 20
max-wait: 1000ms
max-idle: 20
min-idle: 2
datasource:
name: mysql
type: com.alibaba.druid.pool.DruidDataSource
driver-class-name: com.mysql.cj.jdbc.Driver
druid:
url: jdbc:mysql://localhost:3306/bookmark?useUnicode=true&characterEncoding=utf-8&useSSL=false&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTC
username: root
password: 123456
# 其他连接池参数使用默认值
mail:
host:
username:
password:
port: 465
properties:
mail:
smtp:
@ -11,6 +45,8 @@ spring:
starttls:
enable: true
required: true
port: 465
server:
port: 8088
mybatis:
configuration:
log-impl: org.apache.ibatis.logging.commons.JakartaCommonsLoggingImpl
mapper-locations: classpath:mapper/*.xml

View File

@ -0,0 +1,13 @@
CREATE TABLE `user` (
`userId` int UNSIGNED NOT NULL AUTO_INCREMENT,
`username` varchar(20) NOT NULL
COMMENT '用户名20位以内数字字母组合',
`email` varchar(40) NOT NULL,
`icon` varchar(50) NOT NULL,
`password` char(40) NOT NULL
COMMENT '明文6-20位数字密码组合+userId 进行sha1签名',
`createTime` bigint NOT NULL DEFAULT 0,
`lastLoginTime` bigint NOT NULL DEFAULT 0,
PRIMARY KEY (`userId`)
)
ENGINE = InnoDB;