小程序可以通过微信官方提供的登录能力方便地获取微信提供的用户身份标识,快速建立小程序内的用户体系。
登陆流程时序
说明:
1.调用wx.login()获取临时登陆凭证code,并传回开发者服务器 2.调用auth.code2Session接口换取 用户唯一标识 OpenID 、 用户在微信开放平台账号下的唯一标识UnionID(若当前小程序已绑定到微信开放平台账号) 和 会话密钥 session_key。 之后开发者服务器可以根据用户标识来生成自定义登录态,用于后续业务逻辑中前后端交互时识别用户身份。
注意事项
- 会话密钥 session_key 是对用户数据进行 加密签名 的密钥。为了应用自身的数据安全,开发者服务器不应该把会话密钥下发到小程序,也不应该对外提供这个密钥。
- 临时登录凭证 code 只能使用一次
调用方式
HTTPS调用
GET https://api.weixin.qq.com/sns/jscode2session
请求参数
| 属性 | 类型 | 必填 | 说明 |
|---|---|---|---|
| appid | string | 是 | 小程序 appId |
| secret | string | 是 | 小程序 appSecret |
| js_code | string | 是 | 登录时获取的 code,可通过wx.login |
| 获取 | |||
| grant_type | string | 是 | 授权类型,此处只需填写 authorization_code |
返回参数
| 属性 | 类型 | 说明 |
|---|---|---|
| session_key | string | 会话密钥 |
| unionid | string | 用户在开放平台的唯一标识符,若当前小程序已绑定到微信开放平台账号下会返回 |
| errmsg | string | 错误信息 |
| openid | string | 用户唯一标识 |
| errcode | int32 | 错误码 |
示例
HTTP请求
GET https://api.weixin.qq.com/sns/jscode2session?appid=APPID&secret=SECRET&js_code=JSCODE&grant_type=authorization_code
UserController
@RestController
@RequestMapping("user/user")
@Api(tags = "用户接口")
@Slf4j
public class UserController {
@Autowired
private UserService userService;
@Autowired
private JwtProperties jwtProperties;
/**
* 登录
* @param userLoginDTO
* @return
*/
@PostMapping("/login")
@ApiOperation("登录")
public Result<UserLoginVO> login(@RequestBody UserLoginDTO userLoginDTO){
log.info("微信用户登录:{}",userLoginDTO.getCode());
//微信登陆
User user = userService.wxLogin(userLoginDTO);
//生成JWT令牌
Map<String,Object> claims=new HashMap<>();
claims.put(JwtClaimsConstant.USER_ID,user.getId());
String token = JwtUtil.createJWT(jwtProperties.getUserSecretKey(), jwtProperties.getUserTtl(), claims);
UserLoginVO userLoginVO = UserLoginVO.builder()
.id(user.getId())
.openid(user.getOpenid())
.token(token)
.build();
return Result.success(userLoginVO);
}
}
UserService
public interface UserService {
/**
* 微信登陆
* @param userLoginDTO
* @return
*/
User wxLogin(UserLoginDTO userLoginDTO);
}
UserServiceImpl
@Service
@Slf4j
public class UserServiceImpl implements UserService {
//微信服务接口地址
public static final String wxUrl="https://api.weixin.qq.com/sns/jscode2session";
@Autowired
private WeChatProperties weChatProperties;
@Autowired
private UserMapper userMapper;
/**
* 微信登陆
* @param userLoginDTO
* @return
*/
@Override
public User wxLogin(UserLoginDTO userLoginDTO) {
//调研微信接口服务,获取当前微信用户的openId
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(wxUrl, map);
JSONObject jsonObject = JSON.parseObject(json);
String openid = jsonObject.getString("openid");
//判断openId是否为空,如果为空表示登陆失败,抛出业务异常
if(openid==null){
throw new LoginFailedException(MessageConstant.LOGIN_FAILED);
}
//判断当前用户是否为新用户
User user=userMapper.getByOpenid(openid);
//如果是新用户,自动完成注册
if(user==null){
user = User.builder()
.openid(openid)
.createTime(LocalDateTime.now())
.build();
userMapper.insert(user);
}
//返回这个用户对象
return user;
}
}