电脑外设网站建设论文/百度怎么优化排名
文末有本篇文章的项目源码文件可供下载学习
我们在之前实现了SpringSecurity的快速入门+校验数据库用户信息,我们发现SpringSecurity目前只能在它生成的页面上输入Username+Password才能够进行用户登录操作.在前后端分离的场景下,我们需要通过前端页面发送一个登录的URL,该URL上携带Username+Password等信息用于SpringSecurity验证,并且因为项目的不同,我们定义的登录URL中的URI是不同的,所以就需要在之前的基础上实现自定义登录URI.
0.配置思路
- 在本案例(可供下载)的基础上,完善pom.xml,引入相关依赖.
- 配置SecurityConfig.java,加上匿名访问路径/security/login和认证管理器AuthenticationManager
- 新建JwtUtil.java,用于生成和转化jwt字符串.
- 新建CustomerResult.java,用户生成统一的响应信息格式.
- 新建SecurityController.java/SecurityService.java/SecurityServiceImpl.java文件.
- 启动SpringBoot项目,完成相关测试.
1.配置pom.xml
<dependencies>
<!-- web启动器--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency>
<!-- SpringSecurity启动器--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-security</artifactId></dependency>
<!-- mybatis启动器--><dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</artifactId><version>2.1.4</version></dependency>
<!-- mysql驱动--><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>8.0.22</version> <!-- 请检查最新版本 --></dependency>
<!-- lombok--><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><optional>true</optional></dependency>
<!-- fastJson--><dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId><version>1.2.33</version></dependency>
<!-- json序列化中需要用的的辅助包,jdk9+以上就被取消了--><dependency><groupId>javax.xml.bind</groupId><artifactId>jaxb-api</artifactId><version>2.3.1</version></dependency><dependency><groupId>org.glassfish.jaxb</groupId><artifactId>jaxb-runtime</artifactId><version>2.3.1</version></dependency><!-- jwt--><dependency><groupId>io.jsonwebtoken</groupId><artifactId>jjwt</artifactId><version>0.9.0</version></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency></dependencies>
2.配置SecurityConfig.java
@Configuration
public class SecurityConig extends WebSecurityConfigurerAdapter {/*** 用户密码加密处理* @return*/@Beanpublic BCryptPasswordEncoder passwordEncoder() {return new BCryptPasswordEncoder();}@Overrideprotected void configure(HttpSecurity http) throws Exception {http
// 关闭csrf.csrf().disable()
// 不通过session获取SecurityContext.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and().authorizeRequests()// 放行登录接口,允许匿名访问.antMatchers("/security/login").anonymous()
// 登录不登录的都可以访问,放行
// .antMatchers("/hello").permitAll()// 除上面外的所有请求全部需要认证授权.anyRequest().authenticated();}/*** 认证管理器* @return* @throws Exception*/@Bean@Overridepublic AuthenticationManager authenticationManagerBean() throws Exception {return super.authenticationManagerBean();}
}
3.生成JwtUtil.java
public class JwtUtil {public static final Long JWT_TTL = 60*60*1000L; //默认一个小时public static final String JWT_KEY = "secret";public static String getUUID() {return UUID.randomUUID().toString().replace("-", "");}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 (Objects.isNull(ttlMillis)) {ttlMillis = JwtUtil.JWT_TTL;}long expMillis = nowMillis + ttlMillis;Date exp = new Date(expMillis);return Jwts.builder().setId(uuid).setSubject(subject).setIssuer("zerone").setIssuedAt(now).signWith(signatureAlgorithm, secretKey).setExpiration(exp);}public static SecretKey generalKey() {byte[] encodeKey = Base64.getDecoder().decode(JwtUtil.JWT_KEY);SecretKey key = new SecretKeySpec(encodeKey, 0, encodeKey.length,"AES");return key;}public static String createJWT(String uuid, String subject) {JwtBuilder builder = getJwtBuilder(subject,null,uuid);return builder.compact();}public static String createJWT(String subject) {JwtBuilder builder = getJwtBuilder(subject,null,getUUID());return builder.compact();}public static String createJWT(String subject, Long ttlMillis) {JwtBuilder builder = getJwtBuilder(subject,ttlMillis,getUUID());return builder.compact();}public static String createJWT(String subject, Long ttlMillis, String uuid) {return getJwtBuilder(subject,ttlMillis,uuid).compact();}public static Claims parseJWT(String jwt){SecretKey key = generalKey();return Jwts.parser().setSigningKey(key).parseClaimsJws(jwt).getBody();}}
4.生成CustomerResult.java
@Data
@JsonInclude(JsonInclude.Include.NON_NULL)
@AllArgsConstructor
@NoArgsConstructor
public class CustomerResult<T> {private String code;private String msg;private T data;// 链式调用public CustomerResult code(String code) {this.code = code;return this;}public CustomerResult msg(String msg) {this.msg = msg;return this;}public CustomerResult data(T data) {this.data = data;return this;}}
5.新建Controller/Service层代码文件
@RestController
@RequestMapping("security")
public class SecurityController {@Autowiredprivate SecurityService securityService;@PostMapping("login")public CustomerResult login(@RequestBody User user) {return securityService.login(user);}
}
public interface SecurityService {public CustomerResult login(User user);
}
@Service
public class SecurityServiceImpl implements SecurityService {@Autowiredprivate AuthenticationManager authenticationManager;@Autowiredprivate UserMapper userMapper;@Overridepublic CustomerResult login(User user) {
// 1.通过AuthenticationManager对象调用authenticate方法进行验证UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(user.getUsername(), user.getPassword());Authentication authenticate = authenticationManager.authenticate(token);
// 2.如果认证没通过if (Objects.isNull(authenticate)) {throw new RuntimeException("登录失败");}
// 3.如果认证通过,根据userID和UserDetails对象生成jwt,并将jwt放入CustomerResult返回UserDetailsImpl userDetails = (UserDetailsImpl) authenticate.getPrincipal();User currentUser = userDetails.getUser();
// 设置当前用户的当前状态为登录currentUser.setCurrentFlag("login");userMapper.updateCurrentFlagById(currentUser);
// 生成jwtString userDetailsString = JSON.toJSONString(userDetails);String jwt = JwtUtil.createJWT(currentUser.getId(),userDetailsString);
// 对jwt进行封装Map<String, String> map = new HashMap<>();map.put("token", jwt);return new CustomerResult("200","登录成功",map);}
}
6.测试
6.1访问测试
本次测试使用的是IDEA自带的HTTP Client进行测试.
6.2Jwt测试
将生成的token字符串复制下来,赋值给jwtString,进行jwt字符串的解析测试
@Testvoid contextLoads1() {String jwtString = "eyJhbGciOiJIUzI1NiJ9.eyJqdGkiOiJ1c2VySWRfbGlzaSIsInN1YiI6IntcImFjY291bnROb25FeHBpcmVkXCI6dHJ1ZSxcImFjY291bnROb25Mb2NrZWRcIjp0cnVlLFwiY3JlZGVudGlhbHNOb25FeHBpcmVkXCI6dHJ1ZSxcImVuYWJsZWRcIjp0cnVlLFwicGFzc3dvcmRcIjpcIiQyYSQxMCRjMmo2ai9OaUVzSkRYdnVKajNPcGpPWGM3Nk5PSXBVMThQc1ZJWUhocDdBNzVPV202T09KeVwiLFwidXNlclwiOntcImN1cnJlbnRGbGFnXCI6XCJsb2dpblwiLFwiaWRcIjpcInVzZXJJZF9saXNpXCIsXCJwYXNzd29yZFwiOlwiJDJhJDEwJGMyajZqL05pRXNKRFh2dUpqM09wak9YYzc2Tk9JcFUxOFBzVklZSGhwN0E3NU9XbTZPT0p5XCIsXCJ1c2VybmFtZVwiOlwibGlzaVwifSxcInVzZXJuYW1lXCI6XCJsaXNpXCJ9IiwiaXNzIjoiemVyb25lIiwiaWF0IjoxNzQyMjEzMjYzLCJleHAiOjE3NDIyMTY4NjN9.lxeyaUnO91NhGUUoTjXBMGOuey-wB5zI0oLMu6AfCDQ";Claims claims = JwtUtil.parseJWT(jwtString);String id = claims.getId();String subject = claims.getSubject();System.out.println("userId = " + id);System.out.println("==========");System.out.println("subject = " + subject);}
我们发现生成的token中就包含我们的User信息.
本篇文章的项目源码文件,可点击下载学习