项目描述
使用uniapp
框架编写微信小程序,使用自己的后端,实现微信登陆功能。
登录流程
此处参考微信官网提供的 小程序登录流程时序 如下图:
图片来源:微信官方API文档
所以登录的流程即:
- 首先在前端调用
login()
方法获取code
- 拿到
code
后请求我们自己的后端,登录操作由我们自己的后端完成。- 后端接收到
code
,携带code
、appid
和appSecret
后向微信的服务器发送请求,索取该用户的openid。 - 返回
openid
后,与我们的数据库进行对比,寻找绑定该微信的用户,进而实现自定义登录功能。
- 后端接收到
具体实现
1.首先获取 code
(用户登录凭证),像后端发送登录请求。
在 uniapp
框架中,调用 uni.login()
方法,具体方法文档,请见官方文档。
uni.login({provider: 'weixin',onlyAuthorize:true,success: function(loginRes) {uni.request({url: "http://127.0.0.1/login/wechat/" + loginRes.code,success: (res) => {// 处理登录成功}})}
});
2、后端实现登录
2.1 封装请求工具类
后端接收到前端传来的 code
后,需要请求微信接口服务器,获取该微信用户的openid,故我们可以自己封装一个发送请求的工具类。
当然你也可以使用自己常用的发送请求的方式。
package xyz.mumuwei.youthcourseserver.utils;import org.springframework.util.StreamUtils;import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.util.Map;/**
* 网络请求工具类
* @author mumuwei
*/
public class HttpUtil {public static String setHttpRequest(String httpUrl, Map<String, String> params, String requestMethod) throws Exception {//1.定义需要访问的地址URL url = new URL(httpUrl);//2.连接URlHttpURLConnection httpUrlConnection = (HttpURLConnection) url.openConnection();//3.设置请求方式httpUrlConnection.setRequestMethod(requestMethod);//4.携带参数httpUrlConnection.setDoOutput(true);if (params != null && params.size() > 0) {StringBuilder sb = new StringBuilder();for (Map.Entry<String, String> param : params.entrySet()) {sb.append("&").append(param.getKey()).append("=").append(param.getValue());}httpUrlConnection.getOutputStream().write(sb.substring(1).toString().getBytes(StandardCharsets.UTF_8));}//5.发起请求httpUrlConnection.connect();//6.接受返回值return StreamUtils.copyToString(httpUrlConnection.getInputStream(), StandardCharsets.UTF_8);}}
2.2 controller层
/*** 微信登录接口* @param code 用户登录凭证* @return 返回登录 token*/@GetMapping("/login/wechat/{code}")public Result wechatLogin(@PathVariable @NotBlank(message = "校验码不能为空")String code) throws Exception {return wechatService.login(code);}
2.2 service层
Result为自定义返回结果对象,大家可根据自己的项目进行更改。
方法中,对部分逻辑进行了独立封装,主要是便于后期我们进行绑定等操作的重复调用,也提高了代码的可读性。大家根据自己项目实际,决定是否需要单独封装即可。
向微信接口服务器发送请求,获取openid主要参考了 微信的 auth.code2Session
接口,具体可参考官方文档
使用 auth.code2Session
接口,需要提供小程序的 appid
、 appSecret
和 code
, 其中 code
由前端传递,而appid
、 appSecret
需要我们在 微信公众平台自行查看。若不知在什么位置,请看本文末尾介绍。
// 此处我将需要的参数配置在了配置文件中,大家也可以直接写死@Value("${ycms.wechat.appid}")private String appid;@Value("${ycms.wechat.secret}")private String secret;@Value("${ycms.wechat.baseUrl}")private String baseUrl;/*** 微信登录** @param code 用户登录凭证* @return 返回登录 token*/@Overridepublic Result login(String code) throws Exception {String openId = getOpenId(code);if ("".equals(openId)) {return Result.fail("登陆失败,请重试");}// 以下逻辑, 大家可根据自己系统的登录逻辑进行编写// 根据 openid 查询数据库,判断用户是否存在User user = userMapper.selectOne(new QueryWrapper<User>().eq("open_id", openId));if (user == null) {return Result.fail("该微信未绑定");}// 判断用户状态if (user.getState() == 1) {return Result.fail(Const.LOCK_CODE, Const.LOCK_MSG);}// 更新用户登录信息updateUserLoginInfo(user.getId());// 返回数据return Result.success("登录成功", generalToken(user));}/*** 登录凭证校验, 返回 openid, session_key, unionid 等* 详见 https://developers.weixin.qq.com/miniprogram/dev/api-backend/open-api/login/auth.code2Session.html* @param code 登录时获取的 code* @return 请求返回数据* @throws Exception 请求异常*/private String authCode2Session(String code) throws Exception {HashMap<String, String> data = new HashMap<>(5);data.put("appid", appid);data.put("secret", secret);data.put("js_code", code);data.put("grant_type", "authorization_code");return HttpUtil.setHttpRequest(baseUrl + "/sns/jscode2session", data, "GET");}/*** 请求微信服务器, 获取 openid* @param code 登录时获取的 code* @return openid* @throws Exception 异常*/private String getOpenId(String code) throws Exception {// 请求微信服务器,获取用户 oppenidHashMap res = JSON.parseObject(authCode2Session(code), HashMap.class);String openid = res.get("openid").toString();// 请求失败处理if ("".equals(openid) || openid == null) {return "";}// 请求成功,并且返回数据return res.get("openid").toString();}
3、微信公众平台获取小程序信息
获取小程序的 appid
、 appSecret
进入微信公众平台, 登录后,在首页找到 开发管理
然后再右侧,选中 开发设置 -> 开发者ID,就可以找到appid
、 appSecret
了。