一、首先去腾讯开放平台申请相应的appid等,完成后在yml文件配置如下:
constants:
# QQ
qqAppId: *****
qqAppSecret: *****
qqRedirectUrl: *****
#WECHAT
weChatAppId: *****
weChatAppSecret: *****
weChatRedirectUrl: *****
建立配置类Constants:
/**
* 常量配置类
*/
@Configuration
@ConfigurationProperties(prefix = "constants")
public class Constants {
@NotEmpty
private String qqAppId;
@NotEmpty
private String qqAppSecret;
@NotEmpty
private String qqRedirectUrl;
@NotEmpty
private String weChatAppId;
@NotEmpty
private String weChatAppSecret;
@NotEmpty
private String weChatRedirectUrl;
public String getQqAppId() {
return qqAppId;
}
public void setQqAppId(String qqAppId) {
this.qqAppId = qqAppId;
}
public String getQqAppSecret() {
return qqAppSecret;
}
public void setQqAppSecret(String qqAppSecret) {
this.qqAppSecret = qqAppSecret;
}
public String getQqRedirectUrl() {
return qqRedirectUrl;
}
public void setQqRedirectUrl(String qqRedirectUrl) {
this.qqRedirectUrl = qqRedirectUrl;
}
public String getWeChatAppId() {
return weChatAppId;
}
public void setWeChatAppId(String weChatAppId) {
this.weChatAppId = weChatAppId;
}
public String getWeChatAppSecret() {
return weChatAppSecret;
}
public void setWeChatAppSecret(String weChatAppSecret) {
this.weChatAppSecret = weChatAppSecret;
}
public String getWeChatRedirectUrl() {
return weChatRedirectUrl;
}
public void setWeChatRedirectUrl(String weChatRedirectUrl) {
this.weChatRedirectUrl = weChatRedirectUrl;
}
}
二、返回前端登录调用地址:
根据不同的登录类型返回相应的地址,前端直接使用新窗口或者悬浮窗口打开:
public String getLoginUrl(User user) {
if ("1".equals(user.getLoginType())) {
// QQ
return "https://graph.qq.com/oauth2.0/authorize?response_type=code&client_id="
+ constants.getQqAppId()
+ "&redirect_uri="
+ constants.getQqRedirectUrl()
+ "&state="
+ user.getAddress();
} else {
// 微信
try {
return "https://open.weixin.qq.com/connect/qrconnect?appid="
+ constants.getWeChatAppId()
+ "&redirect_uri="
+ constants.getWeChatRedirectUrl()
+ "&response_type=code&scope=snsapi_login&state="
+ URLEncoder.encode(
URLEncoder.encode(user.getAddress(), "utf-8"),
"utf-8") + "#wechat_redirect";
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
return null;
}
}
}
三、前端打开后会出现登录的二维码等,扫描之后会跳转到我们配置的redirect_uri并在url后面返回code参数和我们自定义的state参数
四、根据code拿到accessToken和openid
这一步稍有区别,qq必须先通过code获取accesstoken,再通过accesstoken获取openid;微信则通过code直接获取accesstoken 和openid
qq:
public String getAccessToken(String code) {
String url = "https://graph.qq.com/oauth2.0/token?grant_type=authorization_code&client_id="
+ constants.getQqAppId()
+ "&client_secret="
+ constants.getQqAppSecret()
+ "&code="
+ code
+ "&redirect_uri=" + constants.getQqRedirectUrl();
String resp = RestTemplateUtil.getRestTemplate().getForObject(url,
String.class);
if (resp != null && resp.contains("access_token")) {
Map map = RestTemplateUtil.getParam(resp);
String access_token = map.get("access_token");
return access_token;
}
return null;
}
public String getOpenId(String accessToken) {
String url = "https://graph.qq.com/oauth2.0/me?access_token="
+ accessToken;
String resp = RestTemplateUtil.getRestTemplate().getForObject(url,
String.class);
if (resp != null && resp.contains("openid")) {
JSONObject jsonObject = RestTemplateUtil.convertToJson(resp);
String openid = jsonObject.getString("openid");
return openid;
}
return null;
}
微信:
public AccessToken getAccessToken(String code) {
String url = "https://api.weixin.qq.com/sns/oauth2/access_token?appid="
+ constants.getWeChatAppId() + "&secret="
+ constants.getWeChatAppSecret() + "&code=" + code
+ "&grant_type=authorization_code";
String resp = RestTemplateUtil.getRestTemplate().getForObject(url,
String.class);
if (resp != null && resp.contains("access_token")) {
AccessToken accessToken = JSON.parseObject(resp, AccessToken.class);
return accessToken;
}
return null;
}
AccessToken 对象为:
/**
* 接口调用凭证
*/
private String access_token;
/**
* access_token接口调用凭证超时时间,单位(秒)
*/
private Integer expires_in;
/**
* 用户刷新access_token
*/
private String refresh_token;
/**
* 授权用户唯一标识
*/
private String openid;
/**
* 用户授权的作用域,使用逗号(,)分隔
*/
private String scope;
/**
* 当且仅当该网站应用已获得该用户的userinfo授权时,才会出现该字段。
*/
private String unionid;
五:根据accesstoken 和openid获取用户信息
qq:
public String getUserInfo(String accessToken, String openId) {
String url = "https://graph.qq.com/user/get_user_info?access_token="
+ accessToken + "&oauth_consumer_key=" + constants.getQqAppId()
+ "&openid=" + openId;
String resp = RestTemplateUtil.getRestTemplate().getForObject(url,
String.class);
return resp;
}
微信:
/**
* 获取用户信息
*
* @param accessToken
* @param openId
* @param lang
* 非必须(国家地区语言版本,zh_CN 简体,zh_TW 繁体,en 英语,默认为zh-CN)
* @return
*/
@Override
public String getUserInfo(String accessToken, String openId, String lang) {
String url = "https://api.weixin.qq.com/sns/userinfo?access_token="
+ accessToken + "&openid=" + openId;
if (lang != null && !"".equals(lang)) {
url += "&lang=" + lang;
}
String resp = RestTemplateUtil.getRestTemplate().getForObject(url,
String.class);
return resp;
}