初始化项目

This commit is contained in:
Cool 2023-11-14 18:19:47 +08:00
commit f64b153df6
23 changed files with 904 additions and 0 deletions

79
pom.xml Normal file
View File

@ -0,0 +1,79 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.7.17</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>chat</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>chat</name>
<description>chat</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.auth0</groupId>
<artifactId>java-jwt</artifactId>
<version>3.8.3</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.13</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.2</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.26</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.33</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<!--邮箱发送-->
<dependency>
<groupId>com.sun.mail</groupId>
<artifactId>javax.mail</artifactId>
<version>1.6.2</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>
</project>

View File

@ -0,0 +1,15 @@
package com.example.chat;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class ChatApplication {
public static void main(String[] args) {
SpringApplication.run(ChatApplication.class, args);
}
}

View File

@ -0,0 +1,58 @@
package com.example.chat.controller;
import com.example.chat.entity.Email;
import com.example.chat.entity.Result;
import com.example.chat.entity.User;
import com.example.chat.service.CodeCheck;
import com.example.chat.service.LoginService;
import com.example.chat.service.mail.MailUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import java.io.IOException;
@CrossOrigin
@RestController
public class LoginController {
@Autowired
LoginService login;
@Resource
CodeCheck codeCheck;
@Resource
MailUtil mailUtil;
@PostMapping("/login")
public Result Login(@RequestBody User user) throws IOException {
Result result = new Result();
if (login.LoginCheck(user)!=null) {
result.setStatus(200);
result.setResponseStr(login.LoginCheck(user));
} else {
result.setStatus(200);
result.setResponseStr("No");
}
return result;
}
@PostMapping("/register")
public Result Register(@RequestBody User user) throws IOException {
System.out.println("被调用了");
System.out.println("user是啥"+user);
Result result = new Result();
result.setStatus(login.Register(user));
return result;
}
@PostMapping("/checkCode")
public boolean checkCode(@RequestBody Email email) {
System.out.println(email);
return codeCheck.CheckCode(email.getEmail(),email.getCode());
}
@PostMapping("/sendCode")
public void sendCode(@RequestBody Email email){
System.out.println(email.getEmail());
mailUtil.sendMail(email.getEmail());
}
}

View File

@ -0,0 +1,47 @@
package com.example.chat.dao;
import com.example.chat.entity.User;
import com.example.chat.dao.mybatis.MybatisSingleton;
import org.apache.ibatis.session.SqlSession;
import org.springframework.stereotype.Repository;
import java.io.IOException;
@Repository
public class Login implements UserTable {
@Override
public void addUser(User user) throws IOException {
SqlSession sqlSession=MybatisSingleton.getSqlSessionFactory().openSession();
sqlSession.insert("dao.Login.addUser",user);
sqlSession.commit();
sqlSession.close();
}
@Override
public void delUser(User user) {
}
@Override
public void updateUser(User oldUser,User newUser) {
}
@Override
public User getUser(User user) throws IOException {
SqlSession sqlSession= MybatisSingleton.getSqlSessionFactory().openSession();
User returnUser=sqlSession.selectOne("dao.Login.getUser",user);
sqlSession.close();
return returnUser;
}
@Override
public User emailCheck(User user) throws IOException {
SqlSession sqlSession=MybatisSingleton.getSqlSessionFactory().openSession();
User returnUser=sqlSession.selectOne("dao.Login.emailCheck",user);
sqlSession.close();
return returnUser;
}
}

View File

@ -0,0 +1,26 @@
package com.example.chat.dao;
import com.example.chat.dao.mybatis.MybatisSingleton;
import com.example.chat.entity.User;
import org.apache.ibatis.session.SqlSession;
import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Component;
import java.util.concurrent.TimeUnit;
@Component
public class Test01 implements CommandLineRunner {
@Override
public void run(String... args) throws Exception {
while (true){
SqlSession sqlSession= MybatisSingleton.getSqlSessionFactory().openSession();
User user=sqlSession.selectOne("dao.Login.getUser","123");
if (user!=null){
System.out.println(user);
}
sqlSession.close();
System.out.println("sleep");
TimeUnit.HOURS.sleep(2);
}
}
}

View File

@ -0,0 +1,17 @@
package com.example.chat.dao;
import com.example.chat.entity.User;
import org.springframework.stereotype.Repository;
import java.io.IOException;
@Repository
public interface UserTable {
public abstract void addUser(User user) throws IOException;
public abstract void delUser(User user);
public abstract void updateUser(User oldUser,User newUser);
public abstract User getUser(User user) throws IOException;
public abstract User emailCheck(User user) throws IOException;
}

View File

@ -0,0 +1,23 @@
package com.example.chat.dao.mybatis;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import java.io.IOException;
public class MybatisSingleton {
private static SqlSessionFactory sqlSessionFactory;
private MybatisSingleton(){
}
public static SqlSessionFactory getSqlSessionFactory() throws IOException {
if(sqlSessionFactory==null){
sqlSessionFactory=new SqlSessionFactoryBuilder().build(Resources.getResourceAsReader("mybatis.xml"));
}
return sqlSessionFactory;
}
}

View File

@ -0,0 +1,30 @@
package com.example.chat.dao.redis;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Repository;
import javax.annotation.Resource;
import java.util.concurrent.TimeUnit;
@Repository
public class CodeRedis implements RedisUtil {
@Resource
StringRedisTemplate stringRedisTemplate;
@Override
public void addRedis(String account, String code) {
if (account != null && code != null) {
ValueOperations<String, String> valueOperations = stringRedisTemplate.opsForValue();
valueOperations.set(account, code, 60, TimeUnit.SECONDS);
}
}
@Override
public String getRedis(String account) {
return stringRedisTemplate.opsForValue().get(account);
}
@Override
public void delRedis(String account) {
}
}

View File

@ -0,0 +1,11 @@
package com.example.chat.dao.redis;
import org.springframework.stereotype.Repository;
@Repository
public interface RedisUtil {
public abstract void addRedis(String key,String value);
public abstract void delRedis(String key);
public abstract String getRedis(String key);
}

View File

@ -0,0 +1,30 @@
package com.example.chat.dao.redis;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Repository;
import javax.annotation.Resource;
import java.util.concurrent.TimeUnit;
@Repository
public class TokenRedis implements RedisUtil{
@Resource
StringRedisTemplate stringRedisTemplate;
@Override
public void addRedis(String key, String value) {
ValueOperations<String, String> valueOperations=stringRedisTemplate.opsForValue();
valueOperations.set(key,value,60, TimeUnit.MINUTES);
}
@Override
public void delRedis(String key) {
}
@Override
public String getRedis(String key) {
return stringRedisTemplate.opsForValue().get(key);
}
}

View File

@ -0,0 +1,50 @@
package com.example.chat.entity;
public class Email {
private String email;
private String code;
public Email() {
}
public Email(String email, String code) {
this.email = email;
this.code = code;
}
/**
* 获取
* @return email
*/
public String getEmail() {
return email;
}
/**
* 设置
* @param email
*/
public void setEmail(String email) {
this.email = email;
}
/**
* 获取
* @return code
*/
public String getCode() {
return code;
}
/**
* 设置
* @param code
*/
public void setCode(String code) {
this.code = code;
}
public String toString() {
return "Email{email = " + email + ", code = " + code + "}";
}
}

View File

@ -0,0 +1,70 @@
package com.example.chat.entity;
public class Result {
private int status;
private String responseStr;
private Object data;
public Result() {
}
public Result(int status, String responseStr, Object data) {
this.status = status;
this.responseStr = responseStr;
this.data = data;
}
public Result(int status){
this.status=status;
}
/**
* 获取
* @return status
*/
public int getStatus() {
return status;
}
/**
* 设置
* @param status
*/
public void setStatus(int status) {
this.status = status;
}
/**
* 获取
* @return responseStr
*/
public String getResponseStr() {
return responseStr;
}
/**
* 设置
* @param responseStr
*/
public void setResponseStr(String responseStr) {
this.responseStr = responseStr;
}
/**
* 获取
* @return data
*/
public Object getData() {
return data;
}
/**
* 设置
* @param data
*/
public void setData(Object data) {
this.data = data;
}
public String toString() {
return "Result{status = " + status + ", responseStr = " + responseStr + ", data = " + data + "}";
}
}

View File

@ -0,0 +1,88 @@
package com.example.chat.entity;
public class User {
private String username;
private String password;
private String account;
private String email;
public User() {
}
public User(String username, String password, String account, String email) {
this.username = username;
this.password = password;
this.account = account;
this.email = email;
}
/**
* 获取
* @return username
*/
public String getUsername() {
return username;
}
/**
* 设置
* @param username
*/
public void setUsername(String username) {
this.username = username;
}
/**
* 获取
* @return password
*/
public String getPassword() {
return password;
}
/**
* 设置
* @param password
*/
public void setPassword(String password) {
this.password = password;
}
/**
* 获取
* @return account
*/
public String getAccount() {
return account;
}
/**
* 设置
* @param account
*/
public void setAccount(String account) {
this.account = account;
}
/**
* 获取
* @return email
*/
public String getEmail() {
return email;
}
/**
* 设置
* @param email
*/
public void setEmail(String email) {
this.email = email;
}
public String toString() {
return "User{username = " + username + ", password = " + password + ", account = " + account + ", email = " + email + "}";
}
}

View File

@ -0,0 +1,41 @@
package com.example.chat.jwt;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import java.util.ArrayList;
@Configuration
public class InterceptorConfig implements WebMvcConfigurer {
TokenInterceptor tokenInterceptor;
public InterceptorConfig(TokenInterceptor tokenInterceptor) {//构造函数
this.tokenInterceptor = tokenInterceptor;
}
@Override
public void addInterceptors(InterceptorRegistry registry) {//配置拦截器
System.out.println("拦截器被配置了");
ArrayList<String> excludePath = new ArrayList<>();
excludePath.add("/login");//登录
excludePath.add("/checkCode");
excludePath.add("/sendCode");
excludePath.add("/register");//注册
excludePath.add("/register");
registry.addInterceptor(tokenInterceptor)//注册拦截器
.addPathPatterns("/**")//拦截所有请求
.excludePathPatterns(excludePath);//添加拦截白名单
WebMvcConfigurer.super.addInterceptors(registry);//调用父接口
}
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowCredentials(true)//允许携带cookie
.allowedMethods("GET", "POST", "DELETE", "PUT", "PATCH", "OPTIONS", "HEAD")//允许访问的方法
.allowedOriginPatterns("*")//允许的跨域访问地址
.maxAge(3600 * 24);//options缓存时间
}
}

View File

@ -0,0 +1,34 @@
package com.example.chat.jwt;
import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.interfaces.DecodedJWT;
import org.springframework.stereotype.Component;
public class JWTUtil {
private static final String tokenPassword = "uziCjb";
public static String sign(String username) {//用用户名作为被加密的对象
String token;
token = JWT.create()//生成jwt令牌加密过程
.withIssuer("llh")
.withClaim("username", username)
.sign(Algorithm.HMAC256(tokenPassword));
return token;//返回加密后的token
}
public static String verify(String token){
JWTVerifier jwtVerifier=JWT.require(Algorithm.HMAC256(tokenPassword)).withIssuer("llh").build();//构建一个jwt解码器
DecodedJWT jwtToken=jwtVerifier.verify(token);//解码
if(token.isEmpty()){//若token为空则返回false拦截
return null;
}
else {
System.out.println("认证通过:");
System.out.println("issuer: " + jwtToken.getIssuer());
System.out.println("username: " + jwtToken.getClaim("username").asString());
return jwtToken.getClaim("username").asString();
}
}
}

View File

@ -0,0 +1,57 @@
package com.example.chat.jwt;
import com.example.chat.dao.redis.RedisUtil;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@Component
public class TokenInterceptor implements HandlerInterceptor {
@Resource(name = "tokenRedis")
RedisUtil redisUtil;//注册服务
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
System.out.println("触发拦截");
String token = request.getHeader("Token");
// System.out.println(token + "检查一下token是啥");
// Enumeration<String> headerNames = request.getHeaderNames();
// while (headerNames.hasMoreElements()) {
// String headerName = headerNames.nextElement();
// String headerValue = request.getHeader(headerName);
// System.out.println(headerName + ": " + headerValue);
// }
try {
if (request.getMethod().equals("OPTIONS")) {//检查是否为跨域请求
return true;
}
response.setCharacterEncoding("utf-8");
if (token != null) {
String verifyToken = JWTUtil.verify(token);
if (redisUtil.getRedis(verifyToken)!=null) {
response.setStatus(200);//设置状态码为正常即通过登录验证
System.out.println("通过拦截器");
return true;
} else {
response.setStatus(401);
return false;//redis里没有token即登录超时
}
} else {
response.setStatus(402);
return false;//请求头不带token
}
} catch (Exception exception) {
response.setStatus(500);//发生了不可预测的错误
throw new RuntimeException();
}
}
}

View File

@ -0,0 +1,16 @@
package com.example.chat.service;
import com.example.chat.dao.redis.CodeRedis;
import com.example.chat.dao.redis.RedisUtil;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
@Service
public class CodeCheck {
@Resource(name="codeRedis")
RedisUtil codeRedis;
public boolean CheckCode(String account,String code){
return code.equals(codeRedis.getRedis(account));
}
}

View File

@ -0,0 +1,19 @@
package com.example.chat.service;
import org.springframework.stereotype.Service;
@Service
public class CodeCreate {
public String CreateCode(){
String[] letters = new String[]{
"0", "1", "2", "3", "4", "5", "6", "7",
"8", "9"
};
StringBuilder stringBuilder = new StringBuilder();
for (int i = 0; i < 6; i++) {
stringBuilder.append(letters[(int) Math.floor(Math.random() * letters.length)]);
}
return String.valueOf(stringBuilder);
}
}

View File

@ -0,0 +1,65 @@
package com.example.chat.service;
import com.auth0.jwt.JWT;
import com.example.chat.dao.UserTable;
import com.example.chat.dao.redis.RedisUtil;
import com.example.chat.entity.User;
import com.example.chat.jwt.JWTUtil;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.io.IOException;
@Service
public class LoginService {
@Resource
UserTable userTable;
@Resource(name = "tokenRedis")
RedisUtil redisUtil;
public String LoginCheck(User requestUser) throws IOException {
User user;
user = userTable.getUser(requestUser);
System.out.println(user);
System.out.println(requestUser);
if (user != null) {
if (user.getPassword().equals(requestUser.getPassword())) {
String token= JWTUtil.sign(user.getAccount());
redisUtil.addRedis(user.getAccount(),token);
return token;
} else return null;
}else
{
return null;
}
}
public int Register(User requestUser) throws IOException {
int returnInt = 0;
User user;
user = userTable.getUser(requestUser);
User emailUser = userTable.emailCheck(requestUser);
if (user != null) {
System.out.println("注册有问题");
if (user.getAccount().equals(requestUser.getAccount())) {
returnInt = 1001;//账号已存在
}
// else if (user.getUsername().equals(requestUser.getUsername())) {
// returnInt = 1003;//该用户名已被占用
// }
} else if (emailUser != null) {
if (emailUser.getEmail().equals(requestUser.getEmail())) {
returnInt = 1002;
}
} else {
requestUser.setUsername("用户");
userTable.addUser(requestUser);
returnInt = 200;
}
return returnInt;
}
}

View File

@ -0,0 +1,66 @@
package com.example.chat.service.mail;
import com.example.chat.dao.redis.CodeRedis;
import com.example.chat.dao.redis.RedisUtil;
import com.example.chat.service.CodeCreate;
import com.sun.mail.util.MailSSLSocketFactory;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import javax.mail.*;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import java.security.GeneralSecurityException;
import java.util.Properties;
@Service
public class MailUtil {
@Resource
CodeCreate codeCreate;
@Resource(name ="codeRedis")
RedisUtil redisUtil;
public void sendMail(String receive) {
String code = codeCreate.CreateCode();
Properties prop = new Properties();
//开启debug调试
// prop.setProperty("mail.debug", "true");
//设置邮件服务器主机名
prop.setProperty("mail.host", "smtp.qq.com");
//发送服务器需要身份验证
prop.setProperty("mail.smtp.auth", "true");
//发送邮件协议
prop.setProperty("mail.transport.protocol", "smtp");
try {
MailSSLSocketFactory sslSocketFactory = new MailSSLSocketFactory();
//不对服务器主机名进行验证
sslSocketFactory.setTrustAllHosts(true);
//启用ssl加密
prop.put("mail.smtp.ssl.enable", "true");
prop.put("mail.smtp.ssl.socketFactory", sslSocketFactory);
Session session = Session.getInstance(prop);
Transport transport = session.getTransport();
transport.connect("smtp.qq.com", "747682928@qq.com", "ykrtsjznfvcobfaj");
Message message = createSimpleMail(session, receive, code);
transport.sendMessage(message, message.getAllRecipients());
transport.close();
redisUtil.addRedis(receive,code);
} catch (GeneralSecurityException | MessagingException e) {
throw new RuntimeException(e);
}
}
private MimeMessage createSimpleMail(Session session, String receive, String code) throws MessagingException {
MimeMessage message = new MimeMessage(session);
message.setFrom(new InternetAddress("747682928@qq.com"));
message.setRecipient(Message.RecipientType.TO, new InternetAddress(receive));
//设置邮件标题
message.setSubject("ChatABC");
//设置邮件内容
message.setContent("感谢您在ChatABC的注册,这是您的注册验证码," + code + "<br>如非本人操作,请忽略!请勿回复此邮箱", "text/html;charset=UTF-8");
return message;
}
}

View File

@ -0,0 +1,7 @@
server:
port: 8080
spring:
redis:
port: 6379
password: ob666666
host: 119.29.254.99

View File

@ -0,0 +1,29 @@
<?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="dao.Login">
<select id="getUser" resultType="com.example.chat.entity.User">
select *
from user
where account = #{account};
</select>
<select id="emailCheck" resultType="com.example.chat.entity.User">
select *
from user
where email = #{email};
</select>
<insert id="addUser">
insert into user(account, password, username, email)
values (#{account}, #{password}, #{username}, #{email});
</insert>
<delete id="delUser">
delete
from user
where account = #{account};
</delete>
<update id="updateUser">
update user
set password=#{password} and username = #{username} and email=#{email}
where account = #{account};
</update>
</mapper>

View File

@ -0,0 +1,26 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="com.mysql.cj.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://119.29.254.99:3306/chat"/>
<property name="username" value="root"/>
<property name="password" value="ob666666"/>
</dataSource>
</environment>
</environments>
<!--注册mapper配置文件mapper文件路径配置
url:网络上的映射文件
注意映射配置文件位置要和映射器位置一样映射器在com.mycode.dao里
那么配置文件就应该在resources的com/mycode/dao目录下否则会报
Could not find resource com.mycode.dao.UserMapper.xml类似错误
-->
<mappers>
<!--下面编写mapper映射文件↓↓↓↓↓ 参考格式:<VueLoginMapper.xml resource="dao/VueLoginMapper.xml"/> -->
<mapper resource="mapper/LoginMapper.xml"></mapper>
</mappers>
</configuration>