关于微信第三方的开发,官方文档给了很详细的解析说明,有不清楚流程的同学可以先去官网学习,而我这里主要是整理一下自己的后台处理流程。
其实微信登录就是通过用户的授权,允许app获取用户的微信信息,再往自己的数据库插入获取的信息。
这里用手机app作为例子,当手机选择微信登陆且确认的时候,app会生成一个code,用于获取授权信息,这个code的生命周期只能使用一次,这时候后台可以接受这个code,并获得access_token和openid等信息,有了access_token和openid就能获得该微信用户的信息。
因为以上步骤都是需要appId和秘钥的,所以这两个信息需要放在后台,而不是app客户端。后台操作如下:
后台发送http请求的操作可以使用第三方的okhttp3
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
<version>3.10.0</version>
</dependency>
maven导入需要的jar,编写工具类获取access_token
public static final String APPID = "你的appId";
public static final String SECRET = "你的秘钥";
//获取信息的地址access_token和openId
private static final String ACCESSTOKEN = "https://api.weixin.qq.com/sns/oauth2/access_token";
private static final String WECHATUSERINFO = "https://api.weixin.qq.com/sns/userinfo";
public static Map getAccessToken(String code){
String url = new StringBuilder(ACCESSTOKEN)
.append("?grant_type=authorization_code&appid=").append(APPID).append("&secret=")
.append(SECRET).append("&code=").append(code).toString();
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder().url(url).build();
try {
Response response = client.newCall(request).execute();
String resultJson = response.body().string();
/** 正确返回示例
* "access_token":"ACCESS_TOKEN",
* "expires_in":7200,
* "refresh_token":"REFRESH_TOKEN",
* "openid":"OPENID",
* "scope":"SCOPE",
* "unionid":"o6_bmasdasdsad6_2sgVt7hMZOPfL"
*/
Map parseObject = JSONObject.parseObject(resultJson, Map.class);
//将json专还成map,方便取值
String access_token = (String)parseObject.get("access_token");
if (access_token != null){//有token说明请求正确,返回Map信息
return parseObject;
}
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
调用该方法传入正确的code,能得到我们所需要的信息,到这里为止只是获得了授权和openId的信息,也许你会问openId到底是什么,openId其实就是你微信帐号的唯一标识。
获得到这个map之后,controller层可以这样操作
//得到accesstoken和openId
Map accessToken = WechatUtil.getAccessToken(code);
if (accessToken==null)//请求失败,空就说明刚刚的请求没有发送成功
{
result.put("code",-1);
result.put("msg","第三方登录失败");
return result;
}
//请求成功,获取openId,access_token
String access_token = (String)accessToken.get("access_token");
String open_id = (String)accessToken.get("openid");
/**
*通过openId查找数据库,如果查得到用户说明这个微信号
*登陆过,直接返回这个用户的信息即可,否则就继续调用
*另一个http请求获得用户的信息,然后将这个信息插入的自己的数据库
*/
UserWithBLOBs user = this.userService.getItemByOpenId(open_id);
//没有微信登陆过,发送请求获取微信信息,再添加入库
if (user == null) {
UserWithBLOBs userInfo = WechatUtil.getUserInfo(open_id, access_token);
//将上方的该用户插入到你的数据库且返回到前端
}else {//user!=null用微信登陆过,直接将user放入返回即可
//返回user信息给前端app
}
return result;
获得用户信息的方法,同样使用okhttp3
public static UserWithBLOBs getUserInfo(String openId,String accessToken){
String url = new StringBuilder(WECHATUSERINFO).append("?openid=").append(openId)
.append("&access_token=").append(accessToken).toString();
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder().url(url).build();
try {
Response response = client.newCall(request).execute();
String resultJson = response.body().string();
/**正确的返回信息
* {
* "openid":"OPENID",
* "nickname":"NICKNAME",
* "sex":1,
* "province":"PROVINCE",
* "city":"CITY",
* "country":"COUNTRY",
* "headimgurl": "http://wx.qlogo.cn/mmopen/g3MonUZtNHkdmzicIlibx6iaFqAc56vxLSUfpb6n5WKSYVY0ChQKkiaJSgQ1dZuTOgvLLrhJbERQQ4eMsv84eavHiaiceqxibJxCfHe/0",
* "privilege":[
* "PRIVILEGE1",
* "PRIVILEGE2"
* ],
* "unionid": " o6_bmasdasdsad6_2sgVt7hMZOPfL"
* }
*/
Map parseObject = JSONObject.parseObject(resultJson, Map.class);
String id = (String)parseObject.get("openid");
if (id != null){//成功获取用户信息
String nickname = (String)parseObject.get("nickname");
Integer sex = (Integer)parseObject.get("sex");
String province = (String)parseObject.get("province");
String city = (String)parseObject.get("city");
String headimgurl = (String)parseObject.get("headimgurl");
UserWithBLOBs user = new UserWithBLOBs();
user.setUserName(nickname);
user.setOpenId(openId);
user.setUserImg(headimgurl);
//这里只选了三个字段,根据自己的业务选择更多的字段
return user;
}
}catch (Exception e){
e.printStackTrace();
}
return null;
}
``