需求场景:app端(android/ios)在当下app项目登录时,调用微信第三方拉起授权,如果用户同意,则进行微信登录。
仔细阅读微信官方文档
步骤:1.app端进行请求微信授权登录,若用户同意,将获取得到授权的code
2.app端将code传给服务器端。
3.Java根据APP传过来的code,appId和secret获取得到accessToken和openId(用户唯一标识)
4.用accessToken和openId查询用户信息
5.判断是新用户/老用户登录
实现:
1.在application.yml文件配置appId和secret为公共变量
2.java 代码实现
package com.haidaipuhui.service.app.login.impl;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import org.apache.commons.lang.StringUtils;
import org.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import com.github.pagehelper.util.StringUtil;
import com.haidaipuhui.dao.manage.UserDao;
import com.haidaipuhui.domain.manage.User;
import com.haidaipuhui.enums.StatusEnum;
import com.haidaipuhui.enums.UserSourceEnum;
import com.haidaipuhui.enums.YesOrNoEnum;
import com.haidaipuhui.service.app.login.WeiXinLoginService;
import com.haidaipuhui.service.redis.IRedisService;
import com.haidaipuhui.tokenManager.TokenManager;
import com.haidaipuhui.util.UUIDUtil;
/**
* @author wangdeqiu
* @date 2018年11月12日 上午11:02:03
* 类说明:
*/
@Service
public class WeiXinLoginServiceImpl implements WeiXinLoginService {
private static final Logger logger = LoggerFactory.getLogger(WeiXinLoginServiceImpl.class);
private String WX_AUTH_LOGIN_URL = "https://api.weixin.qq.com/sns/oauth2/access_token";// 获取access_token url
//
private String WX_USERINFO_URL = "https://api.weixin.qq.com/sns/userinfo";// 获取用户信息 url
@Value("${publicvariable.WX_APP_ID}")
private String WX_APP_ID;// appId
@Value("${publicvariable.WX_APP_KEY}")
private String WX_APP_KEY;// AppSecret
@Autowired
private UserDao userDao;
@Autowired
private TokenManager tokenManager;
@Autowired
private IRedisService redisService;
@Override
public Map<String, Object> checkLogin(String code,String deviceToken) throws Exception{
Map<String, Object> outputMap = new HashMap<String,Object>();
if(StringUtil.isEmpty(code)) {
outputMap.put("success", false);
outputMap.put("msg", "必要参数错误");
return outputMap;
}
//获取授权 access_token
StringBuffer loginUrl = new StringBuffer();
loginUrl.append(WX_AUTH_LOGIN_URL).append("?appid=")
.append(WX_APP_ID).append("&secret=")
.append(WX_APP_KEY).append("&code=").append(code)
.append("&grant_type=authorization_code");
System.out.println("-----带有CODE--的URL---"+loginUrl.toString());
String loginRet = this.httpRequest(loginUrl.toString(),"GET",null);
System.out.println("返回信息---------"+loginRet);
JSONObject grantObj = new JSONObject(loginRet);
String errcode = grantObj.optString("errcode");
if (StringUtils.isNotEmpty(errcode))
{
logger.error("------微信登录错误------"+loginRet);
outputMap.put("success", false);
outputMap.put("msg", "登录失败");
return outputMap;
}
String openId = grantObj.optString("openid");
if (StringUtils.isEmpty(openId))
{
logger.error("------微信登录获取OpenId错误------"+loginRet);
outputMap.put("success", false);
outputMap.put("msg", "登录失败");
return outputMap;
}
String accessToken = grantObj.optString("access_token");
//获取用户信息
StringBuffer userUrl = new StringBuffer();
userUrl.append(WX_USERINFO_URL).append("?access_token=").append(accessToken).append("&openid=").append(openId);
// String userRet = this.get(userUrl.toString());
String userRet = this.httpRequest(userUrl.toString(),"GET",null);
logger.info("-----获取得到的用户信息------"+userRet);
JSONObject userObj = new JSONObject(userRet);
String nickname = userObj.optString("nickname");
String sex = userObj.optString("sex");
String userImg = userObj.optString("headimgurl");
//根据openId查询用户信息null--添加(没绑定手机号)
User userInfo = userDao.selectByWechatAndSource(openId,UserSourceEnum.APP.getCode());
//新WX用户
if(userInfo==null) {
//添加信息,设置未绑定手机号
userInfo = new User();
String id = UUIDUtil.getUUID();
userInfo.setId(id);
userInfo.setSex(sex);
userInfo.setWechat(openId);
userInfo.setIsBindmobile(YesOrNoEnum.NO.getCode());
userInfo.setSource(UserSourceEnum.APP.getCode());
userInfo.setName(nickname);
userInfo.setPhoto(userImg);
userInfo.setCreateId(id);
userInfo.setCreateTime(new Date());
userInfo.setStatus(StatusEnum.ENABLE.getCode());
userDao.insertSelective(userInfo);
//缓存设备号
redisService.set(id+"deviceToken", deviceToken);
}
//老WX用户
if(userInfo!=null ) {
}
outputMap.put("openId", openId);
outputMap.put("success", true);
outputMap.put("msg", "成功");
return outputMap;
}
//处理http请求 requestUrl为请求地址 requestMethod请求方式,值为"GET"或"POST"
public String httpRequest(String requestUrl,String requestMethod,String outputStr){
StringBuffer buffer=null;
try{
URL url=new URL(requestUrl);
HttpURLConnection conn=(HttpURLConnection)url.openConnection();
conn.setDoOutput(true);
conn.setDoInput(true);
conn.setRequestMethod(requestMethod);
conn.connect();
//往服务器端写内容 也就是发起http请求需要带的参数
if(null!=outputStr){
OutputStream os=conn.getOutputStream();
os.write(outputStr.getBytes("utf-8"));
os.close();
}
//读取服务器端返回的内容
InputStream is=conn.getInputStream();
InputStreamReader isr=new InputStreamReader(is,"utf-8");
BufferedReader br=new BufferedReader(isr);
buffer=new StringBuffer();
String line=null;
while((line=br.readLine())!=null){
buffer.append(line);
}
logger.info("[weixin]: do get request({}), and get response({}).", url, buffer.toString());
}catch(Exception e){
e.printStackTrace();
}
return buffer.toString();
}
}