diff --git a/backend/pom.xml b/backend/pom.xml index 17390d8..41c755d 100644 --- a/backend/pom.xml +++ b/backend/pom.xml @@ -16,6 +16,32 @@ + + + io.jsonwebtoken + jjwt-jackson + 0.11.5 + runtime + + + + + + io.jsonwebtoken + jjwt-impl + 0.11.5 + runtime + + + + + + io.jsonwebtoken + jjwt-api + 0.11.5 + + + org.springframework.boot spring-boot-starter-security diff --git a/backend/src/main/java/com/kob/backend/BackendApplication.java b/backend/src/main/java/com/kob/backend/BackendApplication.java index 1b2f296..ca43a67 100644 --- a/backend/src/main/java/com/kob/backend/BackendApplication.java +++ b/backend/src/main/java/com/kob/backend/BackendApplication.java @@ -13,3 +13,4 @@ public class BackendApplication { } } + \ No newline at end of file diff --git a/backend/src/main/java/com/kob/backend/config/SecurityConfig.java b/backend/src/main/java/com/kob/backend/config/SecurityConfig.java index ed324e8..acc5287 100644 --- a/backend/src/main/java/com/kob/backend/config/SecurityConfig.java +++ b/backend/src/main/java/com/kob/backend/config/SecurityConfig.java @@ -1,20 +1,48 @@ //实现用户密码的加密存储。==>加上此文件,必须是密文存储 - +//实现公开页面 package com.kob.backend.config; +import com.kob.backend.config.filter.JwtAuthenticationTokenFilter; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import org.springframework.http.HttpMethod; +import org.springframework.security.authentication.AuthenticationManager; +import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; +import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; +import org.springframework.security.config.http.SessionCreationPolicy; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.security.crypto.password.PasswordEncoder; +import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; @Configuration @EnableWebSecurity - -public class SecurityConfig { +public class SecurityConfig extends WebSecurityConfigurerAdapter { + @Autowired + private JwtAuthenticationTokenFilter jwtAuthenticationTokenFilter; @Bean public PasswordEncoder passwordEncoder() { - return new BCryptPasswordEncoder();//返回加密方法 + return new BCryptPasswordEncoder(); + } + + @Bean + @Override + public AuthenticationManager authenticationManagerBean() throws Exception { + return super.authenticationManagerBean(); + } + + @Override + protected void configure(HttpSecurity http) throws Exception { + http.csrf().disable() + .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS) + .and() + .authorizeRequests() + .antMatchers("/user/account/token/", "/user/account/register/").permitAll() + .antMatchers(HttpMethod.OPTIONS).permitAll() + .anyRequest().authenticated(); + + http.addFilterBefore(jwtAuthenticationTokenFilter, UsernamePasswordAuthenticationFilter.class); } -} \ No newline at end of file +} diff --git a/backend/src/main/java/com/kob/backend/config/filter/JwtAuthenticationTokenFilter.java b/backend/src/main/java/com/kob/backend/config/filter/JwtAuthenticationTokenFilter.java new file mode 100644 index 0000000..e901eef --- /dev/null +++ b/backend/src/main/java/com/kob/backend/config/filter/JwtAuthenticationTokenFilter.java @@ -0,0 +1,61 @@ +//用来验证jwt token,如果验证成功,则将User信息注入上下文中 +package com.kob.backend.config.filter; + +import com.kob.backend.mapper.UserMapper; +import com.kob.backend.pojo.User; +import com.kob.backend.service.impl.utils.UserDetailsImpl; +import com.kob.backend.utils.JwtUtil; +import io.jsonwebtoken.Claims; +import org.jetbrains.annotations.NotNull; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.stereotype.Component; +import org.springframework.util.StringUtils; +import org.springframework.web.filter.OncePerRequestFilter; + +import javax.servlet.FilterChain; +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; + +@Component +public class JwtAuthenticationTokenFilter extends OncePerRequestFilter { + @Autowired + private UserMapper userMapper; + + @Override + protected void doFilterInternal(HttpServletRequest request, @NotNull HttpServletResponse response, @NotNull FilterChain filterChain) throws ServletException, IOException { + String token = request.getHeader("Authorization"); + + if (!StringUtils.hasText(token) || !token.startsWith("Bearer ")) { + filterChain.doFilter(request, response); + return; + } + + token = token.substring(7); + + String userid; + try { + Claims claims = JwtUtil.parseJWT(token); + userid = claims.getSubject(); + } catch (Exception e) { + throw new RuntimeException(e); + } + + User user = userMapper.selectById(Integer.parseInt(userid)); + + if (user == null) { + throw new RuntimeException("用户名未登录"); + } + + UserDetailsImpl loginUser = new UserDetailsImpl(user); + UsernamePasswordAuthenticationToken authenticationToken = + new UsernamePasswordAuthenticationToken(loginUser, null, null); + + SecurityContextHolder.getContext().setAuthentication(authenticationToken); + + filterChain.doFilter(request, response); + } +} diff --git a/backend/src/main/java/com/kob/backend/controller/user/UserController.java b/backend/src/main/java/com/kob/backend/controller/user/UserController.java index 7a5f085..474f219 100644 --- a/backend/src/main/java/com/kob/backend/controller/user/UserController.java +++ b/backend/src/main/java/com/kob/backend/controller/user/UserController.java @@ -1,79 +1,79 @@ -package com.kob.backend.controller.user; - - -//@ResponseBody 把return的结果变为Json等数据, -//@Controller 返回jsp,html页面+跳转 -//@Controller + @ResponseBody 返回json等数据 -//@RestController 返回json等数据,不能是jsp,html【@Controller+@responseBody】 - -//@RequestMapping 给出外界访问方法的路径,或者说触发路径 ,触发条件 -//@GetMapping -//PostMapping - -//@AutoWired:自动导入依赖的bean。[用到mapper层的接口时,数据库,写上去] -//byType方式。把配置好的Bean拿来用,完成属性、方法的组装,它可以对类成员变量、方法及构造函数进行标注,完成自动装配的工作。 -//当加上(required=false)时,就算找不到bean也不报错。 -//它可以对类成员变量、方法及构造函数进行标注,让 spring 完成 bean 自动装配的工作。 - -//mapper接口 被mybatis实现 -//接口实例调用mybatis的crud -import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; -import com.kob.backend.mapper.UserMapper; -import com.kob.backend.pojo.User; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; -import org.springframework.security.crypto.password.PasswordEncoder; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.RestController; - -import java.util.List; -//@@@@@@@@@@@@@@@ 实现了【增删查】 @@@@@@@@@@@@@@@@ -@RestController -public class UserController { - - @Autowired - UserMapper userMapper; - - /*查询所有用户*/ - @GetMapping("/user/all/") - public List getAll() - { - return userMapper.selectList(null); - } - - /*查询单个用户*/ - @GetMapping("/user/{userId}/") - public User getUser(@PathVariable int userId) - { - QueryWrapper queryWrapper = new QueryWrapper<>(); - queryWrapper.eq("id",userId); - return userMapper.selectOne(queryWrapper); - // 范围遍历 - // public List getUser(int userId) - // queryWrapper.ge("id", 2).le("id", 3); - // return userMapper.selectList(queryWrapper); - } - - /*添加一个用户*/ - @GetMapping("/user/add/{userId}/{username}/{password}/") - public String addUser(@PathVariable int userId, - @PathVariable String username, - @PathVariable String password) - { - PasswordEncoder passwordEncoder = new BCryptPasswordEncoder(); - String encoderPassword = passwordEncoder.encode(password); - User user = new User(userId,username,encoderPassword); - userMapper.insert(user); - return "Add User Sucessfully"; - } - - /*删除一个用户*/ - @GetMapping("/user/delete/{userId}/") - public String deleteUser(@PathVariable int userId) - { - userMapper.deleteById(userId); - return "Delete User Successfully"; - } - -} \ No newline at end of file +//package com.kob.backend.controller.user; +// +// +////@ResponseBody 把return的结果变为Json等数据, +////@Controller 返回jsp,html页面+跳转 +////@Controller + @ResponseBody 返回json等数据 +////@RestController 返回json等数据,不能是jsp,html【@Controller+@responseBody】 +// +////@RequestMapping 给出外界访问方法的路径,或者说触发路径 ,触发条件 +////@GetMapping +////PostMapping +// +////@AutoWired:自动导入依赖的bean。[用到mapper层的接口时,数据库,写上去] +////byType方式。把配置好的Bean拿来用,完成属性、方法的组装,它可以对类成员变量、方法及构造函数进行标注,完成自动装配的工作。 +////当加上(required=false)时,就算找不到bean也不报错。 +////它可以对类成员变量、方法及构造函数进行标注,让 spring 完成 bean 自动装配的工作。 +// +////mapper接口 被mybatis实现 +////接口实例调用mybatis的crud +//import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +//import com.kob.backend.mapper.UserMapper; +//import com.kob.backend.pojo.User; +//import org.springframework.beans.factory.annotation.Autowired; +//import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; +//import org.springframework.security.crypto.password.PasswordEncoder; +//import org.springframework.web.bind.annotation.GetMapping; +//import org.springframework.web.bind.annotation.PathVariable; +//import org.springframework.web.bind.annotation.RestController; +// +//import java.util.List; +////@@@@@@@@@@@@@@@ 实现了【增删查】 @@@@@@@@@@@@@@@@ +//@RestController +//public class UserController { +// +// @Autowired +// UserMapper userMapper; +// +// /*查询所有用户*/ +// @GetMapping("/user/all/") +// public List getAll() +// { +// return userMapper.selectList(null); +// } +// +// /*查询单个用户*/ +// @GetMapping("/user/{userId}/") +// public User getUser(@PathVariable int userId) +// { +// QueryWrapper queryWrapper = new QueryWrapper<>(); +// queryWrapper.eq("id",userId); +// return userMapper.selectOne(queryWrapper); +// // 范围遍历 +// // public List getUser(int userId) +// // queryWrapper.ge("id", 2).le("id", 3); +// // return userMapper.selectList(queryWrapper); +// } +// +// /*添加一个用户*/ +// @GetMapping("/user/add/{userId}/{username}/{password}/") +// public String addUser(@PathVariable int userId, +// @PathVariable String username, +// @PathVariable String password) +// { +// PasswordEncoder passwordEncoder = new BCryptPasswordEncoder(); +// String encoderPassword = passwordEncoder.encode(password); +// User user = new User(userId,username,encoderPassword,"00"); +// userMapper.insert(user); +// return "Add User Sucessfully"; +// } +// +// /*删除一个用户*/ +// @GetMapping("/user/delete/{userId}/") +// public String deleteUser(@PathVariable int userId) +// { +// userMapper.deleteById(userId); +// return "Delete User Successfully"; +// } +// +//} \ No newline at end of file diff --git a/backend/src/main/java/com/kob/backend/controller/user/account/InfoController.java b/backend/src/main/java/com/kob/backend/controller/user/account/InfoController.java new file mode 100644 index 0000000..1723fa4 --- /dev/null +++ b/backend/src/main/java/com/kob/backend/controller/user/account/InfoController.java @@ -0,0 +1,20 @@ +package com.kob.backend.controller.user.account; + +import com.kob.backend.service.user.account.InfoService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RestController; + +import java.util.Map; + +@RestController +public class InfoController { + @Autowired + private InfoService infoService; + + @GetMapping("/user/account/info/") + public Map getInfo() + { + return infoService.getInfo(); + } +} diff --git a/backend/src/main/java/com/kob/backend/controller/user/account/LoginController.java b/backend/src/main/java/com/kob/backend/controller/user/account/LoginController.java new file mode 100644 index 0000000..b7f7f6d --- /dev/null +++ b/backend/src/main/java/com/kob/backend/controller/user/account/LoginController.java @@ -0,0 +1,31 @@ +package com.kob.backend.controller.user.account; + + +import com.kob.backend.service.user.account.LoginService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +import java.util.Map; + +//@GetMapping 直接从URL获得数据,以www.xxx.com/?id=1类似这种形式传输 +//@PostMapping 请求会从body部分拿到数据,好处是一些不希望用户看到的数据会放在body里面传输。 + +//返回数据 +@RestController +public class LoginController { + @Autowired + private LoginService loginService;//接口实例调用接口方法==>调用实现类中的方法 + + @PostMapping("/user/account/token/") + public Map getToken(@RequestParam Map map) + { + String username = map.get("username"); + String password = map.get("password"); +// System.out.println("------------"); + return loginService.getToken(username,password); + } + +} diff --git a/backend/src/main/java/com/kob/backend/controller/user/account/RegisterController.java b/backend/src/main/java/com/kob/backend/controller/user/account/RegisterController.java new file mode 100644 index 0000000..87b6bbb --- /dev/null +++ b/backend/src/main/java/com/kob/backend/controller/user/account/RegisterController.java @@ -0,0 +1,26 @@ +package com.kob.backend.controller.user.account; + +import com.kob.backend.service.user.account.RegisterService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +import java.util.Map; + +@RestController +public class RegisterController { + + @Autowired + private RegisterService registerService; + + @PostMapping("/user/account/register/") + public Map register(@RequestParam Map map) + { + String username = map.get("username"); + String password = map.get("password"); + String confirmedPassword = map.get("confirmedPassword"); + return registerService.register(username,password,confirmedPassword); + } + +} diff --git a/backend/src/main/java/com/kob/backend/pojo/User.java b/backend/src/main/java/com/kob/backend/pojo/User.java index bec7030..a246af2 100644 --- a/backend/src/main/java/com/kob/backend/pojo/User.java +++ b/backend/src/main/java/com/kob/backend/pojo/User.java @@ -1,5 +1,7 @@ package com.kob.backend.pojo; +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; @@ -15,7 +17,10 @@ import lombok.NoArgsConstructor; @AllArgsConstructor @Data public class User { + + @TableId(type = IdType.AUTO) private Integer id; private String username; private String password; + private String photo; } \ No newline at end of file diff --git a/backend/src/main/java/com/kob/backend/service/impl/UserDetailsServiceImpl.java b/backend/src/main/java/com/kob/backend/service/impl/UserDetailsServiceImpl.java index 38c4047..b703f79 100644 --- a/backend/src/main/java/com/kob/backend/service/impl/UserDetailsServiceImpl.java +++ b/backend/src/main/java/com/kob/backend/service/impl/UserDetailsServiceImpl.java @@ -1,5 +1,5 @@ package com.kob.backend.service.impl; - +//关联数据库 【加载用户通过用户名 返回UserDetails接口实例】====》明文登录 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.kob.backend.mapper.UserMapper; import com.kob.backend.service.impl.utils.UserDetailsImpl; diff --git a/backend/src/main/java/com/kob/backend/service/impl/user/account/InfoServiceImpl.java b/backend/src/main/java/com/kob/backend/service/impl/user/account/InfoServiceImpl.java new file mode 100644 index 0000000..6963601 --- /dev/null +++ b/backend/src/main/java/com/kob/backend/service/impl/user/account/InfoServiceImpl.java @@ -0,0 +1,33 @@ +package com.kob.backend.service.impl.user.account; + +import com.kob.backend.pojo.User; +import com.kob.backend.service.impl.utils.UserDetailsImpl; +import com.kob.backend.service.user.account.InfoService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.stereotype.Service; + +import java.util.HashMap; +import java.util.Map; + +@Service +public class InfoServiceImpl implements InfoService { + @Override + public Map getInfo() { + //获取用户认证 + UsernamePasswordAuthenticationToken authenticationToken = + (UsernamePasswordAuthenticationToken) SecurityContextHolder.getContext().getAuthentication(); + + //取出用户(实例化UserDetailsImp类) + UserDetailsImpl loginUser = (UserDetailsImpl) authenticationToken.getPrincipal(); + User user = loginUser.getUser(); + + Map map = new HashMap<>(); + map.put("error_message","success"); + map.put("id",user.getId().toString()); + map.put("username",user.getUsername()); + map.put("photo",user.getPhoto()); + return map; + } +} diff --git a/backend/src/main/java/com/kob/backend/service/impl/user/account/LoginServiceImpl.java b/backend/src/main/java/com/kob/backend/service/impl/user/account/LoginServiceImpl.java new file mode 100644 index 0000000..54106a8 --- /dev/null +++ b/backend/src/main/java/com/kob/backend/service/impl/user/account/LoginServiceImpl.java @@ -0,0 +1,42 @@ +package com.kob.backend.service.impl.user.account; + +import com.kob.backend.pojo.User; +import com.kob.backend.service.impl.utils.UserDetailsImpl; +import com.kob.backend.service.user.account.LoginService; +import com.kob.backend.utils.JwtUtil; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.authentication.AuthenticationManager; +import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; +import org.springframework.security.core.Authentication; +import org.springframework.stereotype.Service; +//AuthenticationManager(接口) 是认证相关的核心接口,也是发起认证的出发点 +// + +import java.util.HashMap; +import java.util.Map; + +@Service +public class LoginServiceImpl implements LoginService { + + @Autowired + private AuthenticationManager authenticationManager; + + @Override + public Map getToken(String username, String password) { + //将用户名+密码加密封装 + UsernamePasswordAuthenticationToken authenticationToken = + new UsernamePasswordAuthenticationToken(username,password); + //身份认证方法==>登录失败,自动处理 + Authentication authenticate = authenticationManager.authenticate(authenticationToken); + //登录成功==>取出用户(实例化UserDetailsImp类) + UserDetailsImpl loginUser = (UserDetailsImpl) authenticate.getPrincipal(); + User user = loginUser.getUser();//因为UserDetailsImpl有@Data + //取出Token==>通过主键生成jwt_token + String jwt = JwtUtil.createJWT(user.getId().toString()); + + Map map = new HashMap<>(); + map.put("error_message","success"); + map.put("token",jwt); + return map; + } +} diff --git a/backend/src/main/java/com/kob/backend/service/impl/user/account/RegisterServiceImpl.java b/backend/src/main/java/com/kob/backend/service/impl/user/account/RegisterServiceImpl.java new file mode 100644 index 0000000..a28c239 --- /dev/null +++ b/backend/src/main/java/com/kob/backend/service/impl/user/account/RegisterServiceImpl.java @@ -0,0 +1,88 @@ +package com.kob.backend.service.impl.user.account; + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.kob.backend.mapper.UserMapper; +import com.kob.backend.pojo.User; +import com.kob.backend.service.user.account.RegisterService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.crypto.password.PasswordEncoder; +import org.springframework.stereotype.Service; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +@Service +public class RegisterServiceImpl implements RegisterService { + @Autowired + private UserMapper userMapper; + @Autowired + private PasswordEncoder passwordEncoder; + + @Override + public Map register(String username, String password, String confirmedPassword) { + + Map map = new HashMap<>(); + + //判断是否有参数 + if(username == null) + { + map.put("error_message","用户名不能为空"); + return map; + } + + if(password == null || confirmedPassword == null) + { + map.put("error_message","密码不能为空"); + return map; + } + + //判断长度是否为 + username = username.trim(); + if(username.length() == 0) + { + map.put("error_message","用户名不能为空"); + return map; + } + + if(password.length() == 0 || confirmedPassword.length() == 0)//密码可以有空格 + { + map.put("error_message","密码不能为空"); + return map; + } + + if(username.length() > 100) + { + map.put("error_message","用户名长度不能大于100"); + return map; + } + if (password.length() > 100 || confirmedPassword.length() > 100) { + map.put("error_message", "密码不能大于100"); + return map; + } + + if(password.equals(confirmedPassword) == false) + { + map.put("error_message","两次密码不相同"); + return map; + } + + //查询用户名是否已经存在 + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq("username",username); + List users = userMapper.selectList(queryWrapper); + if(!users.isEmpty()){ + map.put("error_message","用户名已存在"); + return map; + } + + //添加一个用户 + String encodedPassword = passwordEncoder.encode(password);//密码 + String photo = "https://cdn.acwing.com/media/user/profile/photo/85918_lg_5ed2550a14.png"; + User user = new User(null,username,encodedPassword,photo); + userMapper.insert(user); + map.put("error_message","success"); + + return map; + } +} diff --git a/backend/src/main/java/com/kob/backend/service/impl/utils/UserDetailsImpl.java b/backend/src/main/java/com/kob/backend/service/impl/utils/UserDetailsImpl.java index e49d92b..fc1c7e4 100644 --- a/backend/src/main/java/com/kob/backend/service/impl/utils/UserDetailsImpl.java +++ b/backend/src/main/java/com/kob/backend/service/impl/utils/UserDetailsImpl.java @@ -1,5 +1,5 @@ package com.kob.backend.service.impl.utils; - +//个人信息接口的实现====》明文登录 import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; @@ -30,6 +30,7 @@ public class UserDetailsImpl implements UserDetails @Override public String getUsername() { return user.getUsername();} + //isAccountNonExpired 账户没有过期 @Override public boolean isAccountNonExpired() {//账号没过期 diff --git a/backend/src/main/java/com/kob/backend/service/user/account/InfoService.java b/backend/src/main/java/com/kob/backend/service/user/account/InfoService.java new file mode 100644 index 0000000..28e984a --- /dev/null +++ b/backend/src/main/java/com/kob/backend/service/user/account/InfoService.java @@ -0,0 +1,11 @@ +package com.kob.backend.service.user.account; +//根据令牌返回用户信息 +import org.springframework.stereotype.Service; + +import java.util.Map; + +@Service +public interface InfoService { + public Map getInfo(); +} + diff --git a/backend/src/main/java/com/kob/backend/service/user/account/LoginService.java b/backend/src/main/java/com/kob/backend/service/user/account/LoginService.java new file mode 100644 index 0000000..9f1436f --- /dev/null +++ b/backend/src/main/java/com/kob/backend/service/user/account/LoginService.java @@ -0,0 +1,11 @@ +package com.kob.backend.service.user.account; + +import org.springframework.stereotype.Service; + +import java.util.Map; + +//验证用户名密码,验证成功后返回 jwt token(令牌) +@Service +public interface LoginService { + public Map getToken(String username,String password); +} diff --git a/backend/src/main/java/com/kob/backend/service/user/account/RegisterService.java b/backend/src/main/java/com/kob/backend/service/user/account/RegisterService.java new file mode 100644 index 0000000..72eddfb --- /dev/null +++ b/backend/src/main/java/com/kob/backend/service/user/account/RegisterService.java @@ -0,0 +1,10 @@ +package com.kob.backend.service.user.account; +//注册账号 +import org.springframework.stereotype.Service; + +import java.util.Map; + +@Service +public interface RegisterService { + public Map register(String username, String password, String confirmedPassword); +} diff --git a/backend/src/main/java/com/kob/backend/utils/JwtUtil.java b/backend/src/main/java/com/kob/backend/utils/JwtUtil.java new file mode 100644 index 0000000..693b1aa --- /dev/null +++ b/backend/src/main/java/com/kob/backend/utils/JwtUtil.java @@ -0,0 +1,63 @@ +//JwtUtil 类为jwt 工具类 用来创建、解析 jwt token +package com.kob.backend.utils; + +import io.jsonwebtoken.Claims; +import io.jsonwebtoken.JwtBuilder; +import io.jsonwebtoken.Jwts; +import io.jsonwebtoken.SignatureAlgorithm; +import org.springframework.stereotype.Component; + +import javax.crypto.SecretKey; +import javax.crypto.spec.SecretKeySpec; +import java.util.Base64; +import java.util.Date; +import java.util.UUID; + +@Component +public class JwtUtil { + public static final long JWT_TTL = 60 * 60 * 1000L * 24 * 14; // 有效期14天 + public static final String JWT_KEY = "SDFGjhdsfalshdfHFdsjkdsfds121232131afasdfac";//密钥 + + public static String getUUID() { + return UUID.randomUUID().toString().replaceAll("-", ""); + } + + public static String createJWT(String subject) { + JwtBuilder builder = getJwtBuilder(subject, null, getUUID()); + return builder.compact(); + } + + private static JwtBuilder getJwtBuilder(String subject, Long ttlMillis, String uuid) { + SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256; + SecretKey secretKey = generalKey(); + long nowMillis = System.currentTimeMillis(); + Date now = new Date(nowMillis); + if (ttlMillis == null) { + ttlMillis = JwtUtil.JWT_TTL; + } + + long expMillis = nowMillis + ttlMillis; + Date expDate = new Date(expMillis); + return Jwts.builder() + .setId(uuid) + .setSubject(subject) + .setIssuer("sg") + .setIssuedAt(now) + .signWith(signatureAlgorithm, secretKey) + .setExpiration(expDate); + } + + public static SecretKey generalKey() { + byte[] encodeKey = Base64.getDecoder().decode(JwtUtil.JWT_KEY); + return new SecretKeySpec(encodeKey, 0, encodeKey.length, "HmacSHA256"); + } + + public static Claims parseJWT(String jwt) throws Exception { + SecretKey secretKey = generalKey(); + return Jwts.parserBuilder() + .setSigningKey(secretKey) + .build() + .parseClaimsJws(jwt) + .getBody(); + } +} \ No newline at end of file diff --git a/web/src/App.vue b/web/src/App.vue index 7afd6f4..3baba51 100644 --- a/web/src/App.vue +++ b/web/src/App.vue @@ -6,33 +6,86 @@ diff --git a/web/src/assets/images/404.jpg b/web/src/assets/images/404.jpg new file mode 100644 index 0000000..595a4a9 Binary files /dev/null and b/web/src/assets/images/404.jpg differ diff --git a/web/src/assets/scripts/AcGameObject.js b/web/src/assets/scripts/AcGameObject.js index b2da0e5..b3ca53f 100644 --- a/web/src/assets/scripts/AcGameObject.js +++ b/web/src/assets/scripts/AcGameObject.js @@ -41,7 +41,6 @@ export class AcGameObject - //上一秒执行的时刻 let last_timestamp; @@ -65,6 +64,7 @@ const step = timestamp => { //【迭代】浏览器每一秒会迭代60次 requestAnimationFrame(step); + } //浏览器刷新 -> 执行一次 diff --git a/web/src/assets/scripts/GameMap.js b/web/src/assets/scripts/GameMap.js index a3b0e00..8354224 100644 --- a/web/src/assets/scripts/GameMap.js +++ b/web/src/assets/scripts/GameMap.js @@ -18,7 +18,7 @@ export class GameMap extends AcGameObject this.walls=[]; - this.inner_walls_count = 0; + this.inner_walls_count = 5; this.snakes = [ new Snake({id:0,color:"#4876ED",r:this.rows-2,c:1},this), diff --git a/web/src/components/NavBar.vue b/web/src/components/NavBar.vue index 6094f89..3327216 100644 --- a/web/src/components/NavBar.vue +++ b/web/src/components/NavBar.vue @@ -25,24 +25,31 @@ -