feat(auth): 添加微信登录功能- 新增微信登录相关配置和接口
- 实现微信登录逻辑,包括获取 openid 和 session_key- 更新安全配置,允许微信登录请求通过 - 添加必要的依赖和数据传输对象
This commit is contained in:
parent
1e4d0abd3a
commit
ae619cc964
|
|
@ -0,0 +1,19 @@
|
|||
package com.example.admin_server.controller.client;
|
||||
|
||||
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 前端控制器
|
||||
* </p>
|
||||
*
|
||||
* @author FallingCliff
|
||||
* @since 2025-05-24
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/api/client/customer")
|
||||
public class CustomerController {
|
||||
|
||||
}
|
||||
|
|
@ -1,9 +1,13 @@
|
|||
package com.example.admin_server.controller.client;
|
||||
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.example.admin_server.common.Result;
|
||||
import com.example.admin_server.config.WxConfig;
|
||||
import com.example.admin_server.model.dto.WxLoginDTO;
|
||||
import com.example.admin_server.model.entity.Customer;
|
||||
import com.example.admin_server.service.ICustomerService;
|
||||
import com.example.admin_server.utils.JwtUtil;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
|
@ -13,6 +17,7 @@ import org.springframework.web.bind.annotation.RequestMapping;
|
|||
import org.springframework.web.bind.annotation.RestController;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
|
|
@ -23,6 +28,8 @@ import java.util.Map;
|
|||
public class WxLoginController {
|
||||
|
||||
private final WxConfig wxConfig;
|
||||
private final ICustomerService iCustomerService;
|
||||
private final JwtUtil jwtUtil;
|
||||
|
||||
@PostMapping("/login")
|
||||
@ApiOperation(value = "微信登录")
|
||||
|
|
@ -32,32 +39,58 @@ public class WxLoginController {
|
|||
return Result.fail("code 参数不能为空");
|
||||
}
|
||||
|
||||
// 构造请求微信的 URL
|
||||
// 请求微信接口
|
||||
String url = wxConfig.getJscode2sessionUrl()
|
||||
+ "?appid=" + wxConfig.getAppid()
|
||||
+ "&secret=" + wxConfig.getSecret()
|
||||
+ "&js_code=" + code
|
||||
+ "&grant_type=authorization_code";
|
||||
|
||||
// 请求微信服务器
|
||||
RestTemplate restTemplate = new RestTemplate();
|
||||
String response = restTemplate.getForObject(url, String.class);
|
||||
|
||||
// 解析微信响应
|
||||
JSONObject jsonObject = JSONObject.parseObject(response);
|
||||
System.out.println(jsonObject);
|
||||
String openid = jsonObject.getString("openid");
|
||||
String sessionKey = jsonObject.getString("session_key");
|
||||
String unionid = jsonObject.getString("unionid");
|
||||
|
||||
if (openid == null) {
|
||||
String errMsg = jsonObject.getString("errmsg");
|
||||
return Result.fail("微信登录失败: " + errMsg);
|
||||
return Result.fail("微信登录失败: " + jsonObject.getString("errmsg"));
|
||||
}
|
||||
|
||||
// TODO: 你可以在这里用 openid 查数据库,创建或更新用户,生成 JWT 等
|
||||
// 查找用户是否已存在
|
||||
Customer customer = iCustomerService.getOne(new QueryWrapper<Customer>().eq("openid", openid));
|
||||
|
||||
if (customer == null) {
|
||||
// 创建新用户
|
||||
customer = new Customer()
|
||||
.setOpenid(openid)
|
||||
.setSessionKey(sessionKey)
|
||||
.setUnionid(unionid)
|
||||
.setNickname("微信用户") // 默认昵称,可后续完善
|
||||
.setAvatarUrl(null)
|
||||
.setCreateTime(LocalDateTime.now())
|
||||
.setUpdateTime(LocalDateTime.now());
|
||||
|
||||
iCustomerService.save(customer);
|
||||
} else {
|
||||
// 更新 session_key 与 update_time
|
||||
customer.setSessionKey(sessionKey);
|
||||
customer.setUpdateTime(LocalDateTime.now());
|
||||
iCustomerService.updateById(customer);
|
||||
}
|
||||
|
||||
Map<String, Object> claims = new HashMap<>();
|
||||
claims.put("id", customer.getId());
|
||||
claims.put("username", customer.getUsername());
|
||||
claims.put("sessionKey", customer.getSessionKey());
|
||||
claims.put("openid", customer.getOpenid());
|
||||
String token = jwtUtil.generateToken(claims);
|
||||
Map<String, Object> resultData = new HashMap<>();
|
||||
resultData.put("token", token);
|
||||
resultData.put("openid", openid);
|
||||
resultData.put("token", "mock-token-" + openid); // 后期你可以用 JWT 替换这里
|
||||
resultData.put("nickname", customer.getNickname());
|
||||
resultData.put("avatar", customer.getAvatarUrl());
|
||||
|
||||
return Result.ok("登录成功", resultData);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,16 @@
|
|||
package com.example.admin_server.mapper;
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.example.admin_server.model.entity.Customer;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Mapper 接口
|
||||
* </p>
|
||||
*
|
||||
* @author FallingCliff
|
||||
* @since 2025-05-24
|
||||
*/
|
||||
public interface CustomerMapper extends BaseMapper<Customer> {
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,82 @@
|
|||
package com.example.admin_server.model.entity;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
*
|
||||
* </p>
|
||||
*
|
||||
* @author FallingCliff
|
||||
* @since 2025-05-24
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = false)
|
||||
@Accessors(chain = true)
|
||||
@TableName("customer")
|
||||
@ApiModel(value="Customer对象", description="客户表")
|
||||
public class Customer implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@ApiModelProperty(value = "主键ID")
|
||||
@TableId(value = "id", type = IdType.AUTO)
|
||||
private Long id;
|
||||
|
||||
@ApiModelProperty(value = "微信openid")
|
||||
@TableField("openid")
|
||||
private String openid;
|
||||
|
||||
@ApiModelProperty(value = "微信会话密钥(可选存储)")
|
||||
@TableField("session_key")
|
||||
private String sessionKey;
|
||||
|
||||
@ApiModelProperty(value = "微信unionid(如果获取到)")
|
||||
@TableField("unionid")
|
||||
private String unionid;
|
||||
|
||||
@ApiModelProperty(value = "用户名")
|
||||
@TableField("username")
|
||||
private String username;
|
||||
|
||||
@ApiModelProperty(value = "密码")
|
||||
@TableField("password")
|
||||
private String password;
|
||||
|
||||
@ApiModelProperty(value = "用户昵称")
|
||||
@TableField("nickname")
|
||||
private String nickname;
|
||||
|
||||
@ApiModelProperty(value = "头像URL")
|
||||
@TableField("avatar_url")
|
||||
private String avatarUrl;
|
||||
|
||||
@ApiModelProperty(value = "邮箱")
|
||||
@TableField("email")
|
||||
private String email;
|
||||
|
||||
@ApiModelProperty(value = "手机号(后续绑定时)")
|
||||
@TableField("phone")
|
||||
private String phone;
|
||||
|
||||
@ApiModelProperty(value = "创建时间")
|
||||
@TableField("create_time")
|
||||
private LocalDateTime createTime;
|
||||
|
||||
@ApiModelProperty(value = "更新时间")
|
||||
@TableField("update_time")
|
||||
private LocalDateTime updateTime;
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
package com.example.admin_server.service;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.example.admin_server.model.entity.Customer;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 服务类
|
||||
* </p>
|
||||
*
|
||||
* @author FallingCliff
|
||||
* @since 2025-05-24
|
||||
*/
|
||||
public interface ICustomerService extends IService<Customer> {
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
package com.example.admin_server.service.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.example.admin_server.mapper.CustomerMapper;
|
||||
import com.example.admin_server.model.entity.Customer;
|
||||
import com.example.admin_server.service.ICustomerService;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 服务实现类
|
||||
* </p>
|
||||
*
|
||||
* @author FallingCliff
|
||||
* @since 2025-05-24
|
||||
*/
|
||||
@Service
|
||||
public class CustomerServiceImpl extends ServiceImpl<CustomerMapper, Customer> implements ICustomerService {
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="com.example.admin_server.mapper.CustomerMapper">
|
||||
|
||||
<!-- 通用查询映射结果 -->
|
||||
<resultMap id="BaseResultMap" type="com.example.admin_server.model.entity.Customer">
|
||||
<id column="id" property="id" />
|
||||
<result column="openid" property="openid" />
|
||||
<result column="session_key" property="sessionKey" />
|
||||
<result column="unionid" property="unionid" />
|
||||
<result column="username" property="username" />
|
||||
<result column="password" property="password" />
|
||||
<result column="nickname" property="nickname" />
|
||||
<result column="avatar_url" property="avatarUrl" />
|
||||
<result column="email" property="email" />
|
||||
<result column="phone" property="phone" />
|
||||
<result column="create_time" property="createTime" />
|
||||
<result column="update_time" property="updateTime" />
|
||||
</resultMap>
|
||||
|
||||
</mapper>
|
||||
Loading…
Reference in New Issue