苍穹外卖--微信登录功能实现&用户端登录校验添加
This commit is contained in:
@@ -1,6 +1,7 @@
|
|||||||
package com.sky.config;
|
package com.sky.config;
|
||||||
|
|
||||||
import com.sky.interceptor.JwtTokenAdminInterceptor;
|
import com.sky.interceptor.JwtTokenAdminInterceptor;
|
||||||
|
import com.sky.interceptor.JwtTokenUserInterceptor;
|
||||||
import com.sky.json.JacksonObjectMapper;
|
import com.sky.json.JacksonObjectMapper;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
@@ -30,6 +31,8 @@ public class WebMvcConfiguration extends WebMvcConfigurationSupport {
|
|||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private JwtTokenAdminInterceptor jwtTokenAdminInterceptor;
|
private JwtTokenAdminInterceptor jwtTokenAdminInterceptor;
|
||||||
|
@Autowired
|
||||||
|
private JwtTokenUserInterceptor jwtTokenUserInterceptor;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 注册自定义拦截器
|
* 注册自定义拦截器
|
||||||
@@ -41,6 +44,10 @@ public class WebMvcConfiguration extends WebMvcConfigurationSupport {
|
|||||||
registry.addInterceptor(jwtTokenAdminInterceptor)
|
registry.addInterceptor(jwtTokenAdminInterceptor)
|
||||||
.addPathPatterns("/admin/**")
|
.addPathPatterns("/admin/**")
|
||||||
.excludePathPatterns("/admin/employee/login");
|
.excludePathPatterns("/admin/employee/login");
|
||||||
|
registry.addInterceptor(jwtTokenUserInterceptor)
|
||||||
|
.addPathPatterns("/user/**")
|
||||||
|
.excludePathPatterns("/user/user/login")
|
||||||
|
.excludePathPatterns("/user/shop/status");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -0,0 +1,47 @@
|
|||||||
|
package com.sky.controller.user;
|
||||||
|
|
||||||
|
import com.sky.constant.JwtClaimsConstant;
|
||||||
|
import com.sky.dto.UserLoginDTO;
|
||||||
|
import com.sky.entity.User;
|
||||||
|
import com.sky.properties.JwtProperties;
|
||||||
|
import com.sky.result.Result;
|
||||||
|
import com.sky.service.UserService;
|
||||||
|
import com.sky.utils.JwtUtil;
|
||||||
|
import com.sky.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;
|
||||||
|
|
||||||
|
@RestController
|
||||||
|
@Slf4j
|
||||||
|
@RequestMapping("/user/user")
|
||||||
|
@Api(tags = "C端用户相关接口")
|
||||||
|
public class UserController {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private UserService userService;
|
||||||
|
@Autowired
|
||||||
|
private JwtProperties jwtProperties;
|
||||||
|
|
||||||
|
@PostMapping("/login")
|
||||||
|
@ApiOperation("微信用户登录")
|
||||||
|
public Result<UserLoginVO> wxLogin(@RequestBody UserLoginDTO userLoginDTO){
|
||||||
|
log.info("微信用户登录:{}",userLoginDTO);
|
||||||
|
//调用业务层微信登录:调用官方的接口获取openID
|
||||||
|
User user = userService.wxLogin(userLoginDTO);
|
||||||
|
//生成jwt令牌的VO对象
|
||||||
|
HashMap<String, Object> claims = new HashMap<>();
|
||||||
|
claims.put(JwtClaimsConstant.USER_ID, user.getId());
|
||||||
|
String jwtToken = JwtUtil.createJWT(jwtProperties.getUserSecretKey(), jwtProperties.getUserTtl(), claims);
|
||||||
|
|
||||||
|
UserLoginVO userLoginVO = UserLoginVO.builder().id(user.getId()).openid(user.getOpenid()).token(jwtToken).build();
|
||||||
|
return Result.success(userLoginVO);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -14,7 +14,7 @@ import javax.servlet.http.HttpServletRequest;
|
|||||||
import javax.servlet.http.HttpServletResponse;
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* jwt令牌校验的拦截器
|
* jwt令牌校验的拦截器--管理端
|
||||||
*/
|
*/
|
||||||
@Component
|
@Component
|
||||||
@Slf4j
|
@Slf4j
|
||||||
|
|||||||
@@ -0,0 +1,66 @@
|
|||||||
|
package com.sky.interceptor;
|
||||||
|
|
||||||
|
import com.sky.constant.JwtClaimsConstant;
|
||||||
|
import com.sky.context.BaseContext;
|
||||||
|
import com.sky.properties.JwtProperties;
|
||||||
|
import com.sky.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;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 校验jwt
|
||||||
|
*
|
||||||
|
* @param request
|
||||||
|
* @param response
|
||||||
|
* @param handler
|
||||||
|
* @return
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
|
||||||
|
//判断当前拦截到的是Controller的方法还是其他资源
|
||||||
|
if (!(handler instanceof HandlerMethod)) {
|
||||||
|
//当前拦截到的不是动态方法,直接放行
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
//1、从请求头中获取令牌
|
||||||
|
String token = request.getHeader(jwtProperties.getUserTokenName());
|
||||||
|
|
||||||
|
//2、校验令牌
|
||||||
|
try {
|
||||||
|
log.info("jwt校验:{}", token);
|
||||||
|
Claims claims = JwtUtil.parseJWT(jwtProperties.getUserSecretKey(), token);
|
||||||
|
Long userId = Long.valueOf(claims.get(JwtClaimsConstant.USER_ID).toString());
|
||||||
|
log.info("当前用户id:", userId);
|
||||||
|
|
||||||
|
log.info("登录校验拦截器所处的线程id:{}",Thread.currentThread().getId());
|
||||||
|
|
||||||
|
//往ThreadLocal中保存当前登录的员工ID
|
||||||
|
BaseContext.setCurrentId(userId);
|
||||||
|
|
||||||
|
//3、通过,放行
|
||||||
|
return true;
|
||||||
|
} catch (Exception ex) {
|
||||||
|
//4、不通过,响应401状态码
|
||||||
|
response.setStatus(401);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
21
sky-server/src/main/java/com/sky/mapper/UserMapper.java
Normal file
21
sky-server/src/main/java/com/sky/mapper/UserMapper.java
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
package com.sky.mapper;
|
||||||
|
|
||||||
|
import com.sky.entity.User;
|
||||||
|
import org.apache.ibatis.annotations.Insert;
|
||||||
|
import org.apache.ibatis.annotations.Mapper;
|
||||||
|
import org.apache.ibatis.annotations.Options;
|
||||||
|
import org.apache.ibatis.annotations.Select;
|
||||||
|
|
||||||
|
/*
|
||||||
|
操作User表
|
||||||
|
*/
|
||||||
|
@Mapper
|
||||||
|
public interface UserMapper {
|
||||||
|
@Select("select * from user where openid = #{openId}")
|
||||||
|
User getByOpenId(String openId);
|
||||||
|
|
||||||
|
@Insert("insert into user (openid, name, phone, sex, id_number, avatar, create_time)" +
|
||||||
|
"values (#{openid},#{name},#{phone},#{sex},#{idNumber},#{avatar},#{createTime})")
|
||||||
|
@Options(useGeneratedKeys = true,keyProperty = "id")//主键回显,得到新用户的主键id
|
||||||
|
void insert(User user);
|
||||||
|
}
|
||||||
13
sky-server/src/main/java/com/sky/service/UserService.java
Normal file
13
sky-server/src/main/java/com/sky/service/UserService.java
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
package com.sky.service;
|
||||||
|
|
||||||
|
import com.sky.dto.UserLoginDTO;
|
||||||
|
import com.sky.entity.User;
|
||||||
|
|
||||||
|
public interface UserService {
|
||||||
|
/**
|
||||||
|
* 微信登录功能
|
||||||
|
* @param userLoginDTO
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
User wxLogin(UserLoginDTO userLoginDTO);
|
||||||
|
}
|
||||||
@@ -0,0 +1,64 @@
|
|||||||
|
package com.sky.service.impl;
|
||||||
|
|
||||||
|
import com.alibaba.fastjson.JSON;
|
||||||
|
import com.alibaba.fastjson.JSONObject;
|
||||||
|
import com.sky.constant.MessageConstant;
|
||||||
|
import com.sky.dto.UserLoginDTO;
|
||||||
|
import com.sky.entity.User;
|
||||||
|
import com.sky.exception.LoginFailedException;
|
||||||
|
import com.sky.mapper.UserMapper;
|
||||||
|
import com.sky.properties.WeChatProperties;
|
||||||
|
import com.sky.service.UserService;
|
||||||
|
import com.sky.utils.HttpClientUtil;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
public class UserServiceImpl implements UserService {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private WeChatProperties weChatProperties;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private UserMapper userMapper;
|
||||||
|
/**
|
||||||
|
* 微信登录功能
|
||||||
|
* @param userLoginDTO
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public User wxLogin(UserLoginDTO userLoginDTO) {
|
||||||
|
//1.调用微信接口服务,获取微信用户唯一标识openID
|
||||||
|
String openId = getOpenId(userLoginDTO);
|
||||||
|
//2.判断openID是否为空
|
||||||
|
if (openId == null) {
|
||||||
|
throw new LoginFailedException(MessageConstant.LOGIN_FAILED);
|
||||||
|
}
|
||||||
|
//3.判断当前用户是否是新用户
|
||||||
|
User user = userMapper.getByOpenId(openId);
|
||||||
|
//4.如果是新用户(数据库中查询不到数据),自动完成注册
|
||||||
|
if (user == null) {
|
||||||
|
user = User.builder().openid(openId).createTime(LocalDateTime.now()).build();
|
||||||
|
userMapper.insert(user);
|
||||||
|
}
|
||||||
|
//5.返回登录对象User
|
||||||
|
return user;
|
||||||
|
}
|
||||||
|
|
||||||
|
//使用httpclient调用微信接口服务
|
||||||
|
private String getOpenId(UserLoginDTO userLoginDTO) {
|
||||||
|
Map<String, String> map = new HashMap<>();
|
||||||
|
map.put("appid",weChatProperties.getAppid());
|
||||||
|
map.put("secret",weChatProperties.getSecret());
|
||||||
|
map.put("js_code", userLoginDTO.getCode());
|
||||||
|
map.put("grant_type"," authorization_code");
|
||||||
|
String json = HttpClientUtil.doGet("https://api.weixin.qq.com/sns/jscode2session", map);
|
||||||
|
JSONObject jsonObject = JSON.parseObject(json);
|
||||||
|
String openid = jsonObject.getString("openid");
|
||||||
|
return openid;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -15,3 +15,6 @@ sky:
|
|||||||
port: 6379
|
port: 6379
|
||||||
password: 123456
|
password: 123456
|
||||||
database: 10 #不配置的话,默认是0号数据库(redis一共有0~15,16个数据库)
|
database: 10 #不配置的话,默认是0号数据库(redis一共有0~15,16个数据库)
|
||||||
|
wechat:
|
||||||
|
appid: wx3a8ed8d8e9c9552a
|
||||||
|
secret: 8ada060abc5326be3a446a75df4c77b3
|
||||||
@@ -42,8 +42,13 @@ sky:
|
|||||||
admin-ttl: 72000000
|
admin-ttl: 72000000
|
||||||
# 设置前端传递过来的令牌名称
|
# 设置前端传递过来的令牌名称
|
||||||
admin-token-name: token
|
admin-token-name: token
|
||||||
|
user-secret-key: inmind
|
||||||
|
user-ttl: 72000000
|
||||||
|
user-token-name: authentication
|
||||||
alioss:
|
alioss:
|
||||||
endpoint: ${sky.alioss.endpoint}
|
endpoint: ${sky.alioss.endpoint}
|
||||||
bucket-name: ${sky.alioss.bucket-name}
|
bucket-name: ${sky.alioss.bucket-name}
|
||||||
region: ${sky.alioss.region}
|
region: ${sky.alioss.region}
|
||||||
|
wechat:
|
||||||
|
appid: ${sky.wechat.appid}
|
||||||
|
secret: ${sky.wechat.secret}
|
||||||
|
|||||||
Reference in New Issue
Block a user