学习使用微信登录接口完成用户登录操作
1.登录流程
微信登录:小程序登录 | 微信开放文档
以最近在做的一个项目为例,其中的微信用户登录流程为:
小程序端,调用wx.login()获取code,就是授权码。
小程序端,调用wx.request()发送请求并携带code,请求后端服务。
服务端,通过HttpClient向微信接口服务的登录凭证校验接口发送请求,并携带appid+secret+code+grant_type三个参数。
服务端,接收微信接口服务返回的数据,session_key+openid等。openid是微信用户的唯一标识。
服务端,根据openid在数据库查询用户,若不存在则注册用户,并查出userId
服务端,自定义登录态,将userId加入JWT令牌(token)中方便后绪请求身份校验。封装UserLoginVo对象返回给小程序,属性包括:userId、openid、token
小程序端,收到自定义登录态,存储storage。
小程序端,后绪通过wx.request()发起业务请求时,携带token。
服务端,收到请求后,通过携带的token,解析当前登录用户的id。
服务端,身份校验通过后,继续相关的业务逻辑处理,最终返回业务数据。
2.小程序端获取临时凭证
调用 wx.login() 获取 临时登录凭证code(js_code)
点击登录后,可以看到控制台输出了临时凭证,再用wx.request()方法将该凭证发送到后端服务器即可
3.后端处理临时凭证
小程序访问/user/user/login接口,后端将临时凭证封装在UserLoginDTO中交给UserService的wxlogin()处理
根据微信服务接口:小程序登录 / 小程序登录 (qq.com)
我们通过HttpClient需要发送GET请求到 https://api.weixin.qq.com/sns/jscode2session 并携带以下参数
从返回的参数中就可以得到openid,即每个微信用户的唯一标识号
通过这个openid就可以查询userId
将userId放入JWT并返回给小程序,小程序后续请求都带上JWT,即可通过解析JWT得到发送该请求的用户的userId
Controller
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
| @RestController @RequestMapping("/user/user") @Slf4j @Api(tags = "C端用户相关接口") public class UserController { @Autowired UserService userService; @Autowired JwtProperties jwtProperties;
@PostMapping("/login") @ApiOperation("登录") public Result<UserLoginVO> wxlogin(@RequestBody UserLoginDTO userLoginDTO){ User user = userService.wxlogin(userLoginDTO); Map<String,Object> claims = new HashMap<>(); claims.put(JwtClaimsConstant.USER_ID,user.getId()); String token = JwtUtil.createJWT(jwtProperties.getUserSecretKey(), jwtProperties.getUserTtl(), claims); UserLoginVO vo = UserLoginVO.builder() .id(user.getId()) .openid(user.getOpenid()) .token(token) .build(); return Result.success(vo); } }
|
ServiceImpl
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
| @Service public class UserServiceImpl implements UserService { public final static String WX_LOGIN = "https://api.weixin.qq.com/sns/jscode2session"; @Autowired WeChatProperties weChatProperties; @Autowired UserMapper userMapper; @Override public User wxlogin(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(WX_LOGIN, map); String openid = JSON.parseObject(json).getString("openid"); if(openid==null){ throw new LoginFailedException(MessageConstant.LOGIN_FAILED); } LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>(); wrapper.eq(User::getOpenid,openid); User user = userMapper.selectOne(wrapper); if(user==null){ user = User.builder().openid(openid).build(); userMapper.insert(user); } return user; } }
|
HttpClientUtil
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182
| import com.alibaba.fastjson.JSONObject; import org.apache.http.NameValuePair; import org.apache.http.client.config.RequestConfig; import org.apache.http.client.entity.UrlEncodedFormEntity; import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.HttpGet; import org.apache.http.client.methods.HttpPost; import org.apache.http.client.utils.URIBuilder; import org.apache.http.entity.StringEntity; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.HttpClients; import org.apache.http.message.BasicNameValuePair; import org.apache.http.util.EntityUtils; import java.io.IOException; import java.net.URI; import java.util.ArrayList; import java.util.List; import java.util.Map;
public class HttpClientUtil {
static final int TIMEOUT_MSEC = 5 * 1000;
public static String doGet(String url,Map<String,String> paramMap){ CloseableHttpClient httpClient = HttpClients.createDefault();
String result = ""; CloseableHttpResponse response = null;
try{ URIBuilder builder = new URIBuilder(url); if(paramMap != null){ for (String key : paramMap.keySet()) { builder.addParameter(key,paramMap.get(key)); } } URI uri = builder.build();
HttpGet httpGet = new HttpGet(uri);
response = httpClient.execute(httpGet);
if(response.getStatusLine().getStatusCode() == 200){ result = EntityUtils.toString(response.getEntity(),"UTF-8"); } }catch (Exception e){ e.printStackTrace(); }finally { try { response.close(); httpClient.close(); } catch (IOException e) { e.printStackTrace(); } }
return result; }
public static String doPost(String url, Map<String, String> paramMap) throws IOException { CloseableHttpClient httpClient = HttpClients.createDefault(); CloseableHttpResponse response = null; String resultString = "";
try { HttpPost httpPost = new HttpPost(url);
if (paramMap != null) { List<NameValuePair> paramList = new ArrayList(); for (Map.Entry<String, String> param : paramMap.entrySet()) { paramList.add( new BasicNameValuePair(param.getKey(), param.getValue()) ); } UrlEncodedFormEntity entity = new UrlEncodedFormEntity(paramList); httpPost.setEntity(entity); }
httpPost.setConfig(builderRequestConfig());
response = httpClient.execute(httpPost);
resultString = EntityUtils.toString(response.getEntity(), "UTF-8"); } catch (Exception e) { throw e; } finally { try { response.close(); } catch (IOException e) { e.printStackTrace(); } }
return resultString; }
public static String doPost4Json(String url, Map<String, String> paramMap) throws IOException { CloseableHttpClient httpClient = HttpClients.createDefault(); CloseableHttpResponse response = null; String resultString = "";
try { HttpPost httpPost = new HttpPost(url);
if (paramMap != null) { JSONObject jsonObject = new JSONObject(); for (Map.Entry<String, String> param : paramMap.entrySet()) { jsonObject.put(param.getKey(),param.getValue()); } StringEntity entity = new StringEntity(jsonObject.toString(),"utf-8"); entity.setContentEncoding("utf-8"); entity.setContentType("application/json"); httpPost.setEntity(entity); }
httpPost.setConfig(builderRequestConfig());
response = httpClient.execute(httpPost);
resultString = EntityUtils.toString(response.getEntity(), "UTF-8"); } catch (Exception e) { throw e; } finally { try { response.close(); } catch (IOException e) { e.printStackTrace(); } }
return resultString; } private static RequestConfig builderRequestConfig() { return RequestConfig.custom() .setConnectTimeout(TIMEOUT_MSEC) .setConnectionRequestTimeout(TIMEOUT_MSEC) .setSocketTimeout(TIMEOUT_MSEC).build(); }
}
|