Skip to content

Commit

Permalink
用户微信端登录
Browse files Browse the repository at this point in the history
  • Loading branch information
Q-1515 committed Jul 23, 2022
1 parent 35c0003 commit cf15b56
Show file tree
Hide file tree
Showing 9 changed files with 372 additions and 1 deletion.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ Spring Task
4. Node.js v16.15.1
5. Redis 7.0
6. MySQL 5.6.22
7. 微信开发者工具

## 前后端分离开发

Expand Down
Binary file added img.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
package com.reggie.Interceptor;

import com.reggie.annotation.IgnoreToken;
import com.reggie.constant.JwtClaimsConstant;
import com.reggie.context.BaseContext;
import com.reggie.properties.JwtProperties;
import com.reggie.utils.JwtUtil;
import io.jsonwebtoken.Claims;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
* 统一进行jwt校验
*/
@Component
@Slf4j
public class JwtTokenUserInterceptor implements HandlerInterceptor {
@Autowired
private JwtProperties jwtProperties;

/**
* 客户端令牌校验
*/
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
log.info("拦截到了请求:{}", request.getRequestURI());

if (handler instanceof HandlerMethod) {
//如果不是映射到controller某个方法的请求,则直接放行,例如请求的是/doc.html
return true;
}

//判断当前被拦截的Controller方法上是否加入了IgonreToken注解
HandlerMethod handlerMethod = (HandlerMethod) handler;

//加入了IgnoreToken注解,直接放行
boolean hasMethodAnnotation = handlerMethod.hasMethodAnnotation(IgnoreToken.class);
if (hasMethodAnnotation) {
return true;
}

//从请求头获取jwt令牌
String jwt = request.getHeader(jwtProperties.getUserTokenName());

try {
//解析jwt令牌
Claims claims = JwtUtil.parseJWT(jwtProperties.getUserSecretKey(), jwt);
//获取当前登录用户的id
Long userId = Long.valueOf(claims.get(JwtClaimsConstant.USER_ID).toString());
// 保存当前登录用户的id到线程本地变量
BaseContext.setCurrentId(userId);
} catch (Exception e) {
log.info("令牌解析失败");
//401代表用户没有访问权限,需要进行身份认证
response.setStatus(401);
return false;
}
return true;
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.reggie.config;

import com.reggie.Interceptor.JwtTokenAdminInterceptor;
import com.reggie.Interceptor.JwtTokenUserInterceptor;
import com.reggie.json.JacksonObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
Expand All @@ -26,12 +27,19 @@ public class WebMvcConfiguration extends WebMvcConfigurationSupport {
@Autowired
private JwtTokenAdminInterceptor jwtTokenAdminInterceptor;

@Autowired
private JwtTokenUserInterceptor jwtTokenUserInterceptor;

@Override
protected void addInterceptors(InterceptorRegistry registry) {
log.info("开始注册自定义拦截器...");
registry.addInterceptor(jwtTokenAdminInterceptor)
.addPathPatterns("/admin/**")
.excludePathPatterns("/admin/employee/login");
.excludePathPatterns("/admin/employee/login", "/admin/employee/logout");

registry.addInterceptor(jwtTokenUserInterceptor)
.addPathPatterns("/user/**")
.excludePathPatterns("/user/user/login");
}

/**
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
package com.reggie.controller.user;

import com.reggie.constant.JwtClaimsConstant;
import com.reggie.dto.UserLoginDTO;
import com.reggie.entity.User;
import com.reggie.properties.JwtProperties;
import com.reggie.result.R;
import com.reggie.service.UserService;
import com.reggie.utils.JwtUtil;
import com.reggie.vo.UserLoginVO;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.HashMap;
import java.util.Map;

@RestController
@RequestMapping("/user/user")
@Slf4j
@Api(tags = "C端-用户接口")
public class UserController {

@Autowired
private UserService userService;
@Autowired
private JwtProperties jwtProperties;

/**
* C端用户登录--微信登录
*
* @param userLoginDTO //微信授权码
* @return 用户id,微信openid,jwt令牌
*/
@PostMapping("/login")
@ApiOperation("登录")
public R<UserLoginVO> login(@RequestBody UserLoginDTO userLoginDTO) {
log.info("微信小程序登录:{}", userLoginDTO);
User user = userService.wxLogin(userLoginDTO);

//设置用户id为唯一参数
Map<String, Object> claims = new HashMap<>();
claims.put(JwtClaimsConstant.USER_ID, user.getId());
//创建jwt令牌
String token = JwtUtil.createJWT(jwtProperties.getUserSecretKey(), jwtProperties.getUserTtl(), claims);
UserLoginVO loginVO = UserLoginVO.builder()
.id(user.getId())
.openid(user.getOpenid())
.token(token)
.build();
return R.success(loginVO);
}

/**
* 退出
*
* @return success
*/
@PostMapping("/logout")
@ApiOperation("退出")
public R<String> logout() {
return R.success();
}
}
53 changes: 53 additions & 0 deletions reggie_server/src/main/java/com/reggie/mapper/UserMapper.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
package com.reggie.mapper;

import com.reggie.entity.User;
import org.apache.ibatis.annotations.Mapper;

import java.util.List;

@Mapper
public interface UserMapper {

/**
* 插入
*
* @param user
*/
public void insert(User user);

/**
* 根据主键查询
*
* @param id
* @return
*/
public User getById(Long id);

/**
* 根据id修改
*
* @param user
*/
public void update(User user);

/**
* 根据主键删除
*
* @param id
*/
public void deleteById(Long id);

/**
* 条件查询
*
* @param user
* @return
*/
public List<User> list(User user);

/**
* 根据openid查询用户
* @return
*/
public User getByOpenid(String openid);
}
10 changes: 10 additions & 0 deletions reggie_server/src/main/java/com/reggie/service/UserService.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package com.reggie.service;

import com.reggie.dto.UserLoginDTO;
import com.reggie.entity.User;

public interface UserService {

//微信登录
User wxLogin(UserLoginDTO userLoginDTO);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
package com.reggie.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.reggie.constant.MessageConstant;
import com.reggie.dto.UserLoginDTO;
import com.reggie.entity.User;
import com.reggie.exception.LoginFailedException;
import com.reggie.mapper.UserMapper;
import com.reggie.service.UserService;
import com.reggie.utils.HttpClientUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.Map;

@Service
@Slf4j
public class UserServiceImpl implements UserService {
public static final String LOGIN_URL = "https://api.weixin.qq.com/sns/jscode2session";

@Autowired
private UserMapper userMapper;

@Value("${reggie.wechat.appid}")
private String appid;

@Value("${reggie.wechat.secret}")
private String secret;


private String getOpenid(String code) {
Map<String, String> param = new HashMap<>();
param.put("appid",appid);
param.put("secret",secret);
param.put("js_code",code);
param.put("grant_type","authorization_code");

//数据格式:{openid:xxxx,session_key:xxxx}
String res = HttpClientUtil.doGet(LOGIN_URL, param);
JSONObject jsonObject = JSON.parseObject(res);
String openid = jsonObject.getString("openid");
log.info("查询到微信用户的openid:{}", openid);
return openid;
}

/**
* 微信登陆
*
* @param userLoginDTO 微信授权码
* @return 用户信息
*/
public User wxLogin(UserLoginDTO userLoginDTO) {
String code = userLoginDTO.getCode();

//获取微信用户的openid
String openid = getOpenid(code);

if (openid == null) {
throw new LoginFailedException(MessageConstant.LOGIN_FAILED);
}

//根据openid查询用户
User user = userMapper.getByOpenid(openid);
if (user == null) {
//新用户自动注册
user = new User();
user.setOpenid(openid);
user.setCreateTime(LocalDate.now());
userMapper.insert(user);
}
return user;
}

}
Loading

0 comments on commit cf15b56

Please sign in to comment.