本文主要是介绍Yshop框架的小程序登录,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
1配置
根据请求头去判断,走小程序,还是Pc端。
#jwt
jwt:header: Authorization#小程序前缀 请求头mini-program-header: MiAuthorization# 令牌前缀token-start-with: Bearersecret: k09BQnaF# 必须使用最少88位的Base64对该令牌进行编码base64-secret: ZmQ0ZGI5NjQ0MDQwY2I4MjMxY2Y3ZmI3MjdhN2ZmMjNhODViOTg1ZGE0NTBjMGM4NDA5NzYxMjdjOWMwYWRmZTBlZjlhNGY3ZTg4Y2U3YTE1ODVkZDU5Y2Y3OGYwZWE1NzUzNWQ2YjFjZDc0NGMxZWU2MmQ3MjY1NzJmNTE0MzI=# 令牌过期时间 此处单位/毫秒 ,默认4小时,可在此网站生成 https://www.convertworld.com/zh-hans/time/milliseconds.htmltoken-validity-in-seconds: 14400000# 在线用户keyonline-key: online-token# 小程序在线用户mi-online-key: mi-online-token# 验证码code-key: code-key
2.登录
登录时,设置用户信息存储到redis中。
/**** 根据账户,密码 登录* @param exUser* @return*/@Overridepublic R<Object> VxLogin(ExUser exUser) {// 查询数据库中的账号密码是否存在ExUser exUserA = exUserMapper.selectOne(new LambdaQueryWrapper<ExUser>().eq(StringUtils.isNotBlank(exUser.getUserUsername()), ExUser::getUserUsername, exUser.getUserUsername()).eq(StringUtils.isNotBlank(exUser.getUserPassword()), ExUser::getUserPassword, exUser.getUserPassword()).eq(Objects.nonNull(exUser.getUserStatus()), ExUser::getUserStatus, 1));if (Objects.isNull(exUserA)) {return R.error("该用户未存在");}// 生成tokenString token = tokenUtil.generateTokenA(exUserA);Map<String, Object> authInfo = new HashMap<String, Object>(2) {{put("token", properties.getTokenStartWith() + token);put("user", exUserA);}};RedisUtil.set(properties.getMiOnlineKey() + token, exUserA, properties.getTokenValidityInSeconds() / 1000);return R.success(authInfo);}
3.过滤器
获取请求头,判断是小程序接口还是Pc端接口。
/*** Copyright (C) 2018-2022* All rights reserved, Designed By www.yixiang.co*/
package co.yixiang.modules.security.security;import co.yixiang.domain.ExUser;
import co.yixiang.modules.security.config.SecurityProperties;
import co.yixiang.modules.security.service.OnlineUserService;
import co.yixiang.modules.user.vo.OnlineUser;
import co.yixiang.utils.SpringContextHolder;
import co.yixiang.utils.StringUtils;
import io.jsonwebtoken.ExpiredJwtException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
import org.springframework.web.filter.GenericFilterBean;import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;/*** @author /*/
@Slf4j
public class TokenFilter extends GenericFilterBean {@Autowiredprivate SecurityProperties securityProperties;private final TokenUtil tokenUtil;TokenFilter(TokenUtil tokenUtil) {this.tokenUtil = tokenUtil;}@Overridepublic void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain)throws IOException, ServletException {HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest;String requestRri = httpServletRequest.getRequestURI();OnlineUser onlineUser = null;ExUser exUser = null;String authToken = null;String authTokenA = null;try {SecurityProperties properties = SpringContextHolder.getBean(SecurityProperties.class);OnlineUserService onlineUserService = SpringContextHolder.getBean(OnlineUserService.class);String clientType = httpServletRequest.getHeader(properties.getHeader());String miniProgramClientType = httpServletRequest.getHeader(properties.getMiniProgramHeader());// 检查是否存在PC端或小程序端的请求头if (clientType == null && miniProgramClientType == null) {log.error("Both Client-Type and Mini-Program-Client-Type headers are missing.");filterChain.doFilter(httpServletRequest, servletResponse);return;}if (StringUtils.isNotBlank(clientType)) {// PC端authToken = tokenUtil.getToken(httpServletRequest);} else if (StringUtils.isNotBlank(miniProgramClientType)) {// 小程序authTokenA = tokenUtil.getTokenA(httpServletRequest);}if (authToken == null && authTokenA == null) {log.error("Both authToken and authTokenA are null.");filterChain.doFilter(httpServletRequest, servletResponse);return;}if (StringUtils.isNotBlank(authToken)) {onlineUser = onlineUserService.getOne(properties.getOnlineKey() + authToken);} else if (StringUtils.isNotBlank(authTokenA)) {exUser = onlineUserService.getOneA(properties.getMiOnlineKey() + authTokenA);
// String userJson = RedisUtil.get("userA");
// ExUser user = JSON.parseObject(userJson, ExUser.class);}} catch (ExpiredJwtException e) {log.error(e.getMessage());}// PcString username = StringUtils.isNotBlank(authToken) ? tokenUtil.getUsernameFromToken(authToken) : null;// 小程序String usernameA = StringUtils.isNotBlank(authTokenA) ? tokenUtil.getUsernameFromToken(authTokenA) : null;if (onlineUser != null && username != null && SecurityContextHolder.getContext().getAuthentication() == null && tokenUtil.validateToken(authToken)) {UserDetails userDetails = tokenUtil.getUserDetails(authToken);UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities());authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails(httpServletRequest));SecurityContextHolder.getContext().setAuthentication(authentication);log.debug("set Authentication to security context for '{}', uri: {}", authentication.getName(), requestRri);}else if(exUser != null && usernameA != null && SecurityContextHolder.getContext().getAuthentication() == null && tokenUtil.validateTokenA(authTokenA)){UserDetails userDetailsA = tokenUtil.getUserDetailsA(authTokenA);UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(userDetailsA, null, null);authenticationToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(httpServletRequest));SecurityContextHolder.getContext().setAuthentication(authenticationToken);}else {tokenUtil.removeToken(authToken);tokenUtil.removeToken(authTokenA);log.debug("no valid JWT token found, uri: {}", requestRri);}filterChain.doFilter(httpServletRequest, servletResponse);}
}
4. 工具类完善
/*** Copyright (C) 2018-2022* All rights reserved, Designed By www.yixiang.co*/
package co.yixiang.modules.security.security;import co.yixiang.domain.ExUser;
import co.yixiang.modules.security.config.SecurityProperties;
import co.yixiang.modules.security.service.OnlineUserService;
import co.yixiang.modules.user.vo.OnlineUser;
import co.yixiang.utils.SpringContextHolder;
import co.yixiang.utils.StringUtils;
import io.jsonwebtoken.ExpiredJwtException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
import org.springframework.web.filter.GenericFilterBean;import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;/*** @author /*/
@Slf4j
public class TokenFilter extends GenericFilterBean {@Autowiredprivate SecurityProperties securityProperties;private final TokenUtil tokenUtil;TokenFilter(TokenUtil tokenUtil) {this.tokenUtil = tokenUtil;}@Overridepublic void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain)throws IOException, ServletException {HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest;String requestRri = httpServletRequest.getRequestURI();OnlineUser onlineUser = null;ExUser exUser = null;String authToken = null;String authTokenA = null;try {SecurityProperties properties = SpringContextHolder.getBean(SecurityProperties.class);OnlineUserService onlineUserService = SpringContextHolder.getBean(OnlineUserService.class);String clientType = httpServletRequest.getHeader(properties.getHeader());String miniProgramClientType = httpServletRequest.getHeader(properties.getMiniProgramHeader());// 检查是否存在PC端或小程序端的请求头if (clientType == null && miniProgramClientType == null) {log.error("Both Client-Type and Mini-Program-Client-Type headers are missing.");filterChain.doFilter(httpServletRequest, servletResponse);return;}if (StringUtils.isNotBlank(clientType)) {// PC端authToken = tokenUtil.getToken(httpServletRequest);} else if (StringUtils.isNotBlank(miniProgramClientType)) {// 小程序authTokenA = tokenUtil.getTokenA(httpServletRequest);}if (authToken == null && authTokenA == null) {log.error("Both authToken and authTokenA are null.");filterChain.doFilter(httpServletRequest, servletResponse);return;}if (StringUtils.isNotBlank(authToken)) {onlineUser = onlineUserService.getOne(properties.getOnlineKey() + authToken);} else if (StringUtils.isNotBlank(authTokenA)) {exUser = onlineUserService.getOneA(properties.getMiOnlineKey() + authTokenA);
// String userJson = RedisUtil.get("userA");
// ExUser user = JSON.parseObject(userJson, ExUser.class);}} catch (ExpiredJwtException e) {log.error(e.getMessage());}// PcString username = StringUtils.isNotBlank(authToken) ? tokenUtil.getUsernameFromToken(authToken) : null;// 小程序String usernameA = StringUtils.isNotBlank(authTokenA) ? tokenUtil.getUsernameFromToken(authTokenA) : null;if (onlineUser != null && username != null && SecurityContextHolder.getContext().getAuthentication() == null && tokenUtil.validateToken(authToken)) {UserDetails userDetails = tokenUtil.getUserDetails(authToken);UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities());authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails(httpServletRequest));SecurityContextHolder.getContext().setAuthentication(authentication);log.debug("set Authentication to security context for '{}', uri: {}", authentication.getName(), requestRri);}else if(exUser != null && usernameA != null && SecurityContextHolder.getContext().getAuthentication() == null && tokenUtil.validateTokenA(authTokenA)){UserDetails userDetailsA = tokenUtil.getUserDetailsA(authTokenA);UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(userDetailsA, null, null);authenticationToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(httpServletRequest));SecurityContextHolder.getContext().setAuthentication(authenticationToken);}else {tokenUtil.removeToken(authToken);tokenUtil.removeToken(authTokenA);log.debug("no valid JWT token found, uri: {}", requestRri);}filterChain.doFilter(httpServletRequest, servletResponse);}
}
5. 获取当前用户数据的工具
判断该接口是否被类实现
/*** Copyright (C) 2018-2022* All rights reserved, Designed By www.yixiang.co*/
package co.yixiang.utils;import cn.hutool.json.JSONObject;
import co.yixiang.domain.ExUser;
import co.yixiang.exception.BadRequestException;
import org.springframework.http.HttpStatus;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;/*** 获取当前登录的用户* @author Zheng Jie* @date 2019-01-17*/
public class SecurityUtils {public static UserDetails getUserDetails() {final Authentication authentication = SecurityContextHolder.getContext().getAuthentication();if (authentication == null) {throw new BadRequestException(HttpStatus.UNAUTHORIZED, "当前登录状态过期");}if(authentication.getPrincipal() instanceof ExUser){return (UserDetails) authentication.getPrincipal();}if (authentication.getPrincipal() instanceof UserDetails) {UserDetails userDetails = (UserDetails) authentication.getPrincipal();UserDetailsService userDetailsService = SpringContextHolder.getBean(UserDetailsService.class);return userDetailsService.loadUserByUsername(userDetails.getUsername());}throw new BadRequestException(HttpStatus.UNAUTHORIZED, "找不到当前登录的信息");}/*** 获取系统用户名称* @return 系统用户名称*/public static String getUsername(){final Authentication authentication = SecurityContextHolder.getContext().getAuthentication();if (authentication == null) {throw new BadRequestException(HttpStatus.UNAUTHORIZED, "当前登录状态过期");}UserDetails userDetails = (UserDetails) authentication.getPrincipal();return userDetails.getUsername();}/*** 获取系统用户id* @return 系统用户id*/public static Long getUserId(){Object obj = getUserDetails();JSONObject json = new JSONObject(obj);return json.get("id", Long.class);}
}
这篇关于Yshop框架的小程序登录的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!