java實現(xiàn)微信掃碼登錄第三方網(wǎng)站功能(原理和代碼)
為避免繁瑣的注冊登陸,很多平臺和網(wǎng)站都會實現(xiàn)三方登陸的功能,增強用戶的粘性。這篇文章主要介紹了java實現(xiàn)微信掃碼登錄第三方網(wǎng)站功能(原理和代碼),避免做微信登錄開發(fā)的朋友們少走彎路。
一.查看微信掃碼登錄官方文檔
1.在進行第三方授權登錄之前,需要在微信開放平臺注冊開發(fā)者賬號,拿到相應的AppId和AppSecret以及redirect_uri,即可進行授權接入流程;
2.第三方可以獲取到用戶的接口調(diào)用憑證(access_token),通過access_token可以進行微信開放平臺授權關系接口調(diào)用,從而可實現(xiàn)獲取微信用戶基本開放信息和幫助用戶實現(xiàn)基礎開放功能等。
獲取access_token時序圖:

二.實現(xiàn)微信第三方登錄流程:
1. 開發(fā)者調(diào)用微信接口用于獲取掃描二維碼。
調(diào)用接口:
參數(shù)介紹:
appid: 微信申請已存在的服務號的應用號;
redirect_uri: 回調(diào)地址,掃完碼之后微信會將code這個值傳到這個地址上,注意:回調(diào)地址需要用urlEncode處理;
responseType: 填code;
scope: 網(wǎng)頁應用僅填snsapi_login;
state: 用于保持請求和回調(diào)的狀態(tài),授權請求后原樣帶給第三方,可用于防止跨站攻擊;
2. 用戶掃描二維碼后該接口會自動返回重定向的資源上,并且?guī)蟘ode和state參數(shù),如果用戶拒絕授權只會帶上state參數(shù)
3. 開發(fā)者通過用微信另一個接口根據(jù)code和 appid,secret獲取access_token(也就是調(diào)用接口的憑證,有了他可以獲取里面的openid等信息)
調(diào)用接口:
https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code
- 參數(shù)介紹
appid: 微信申請已存在的服務號的應用號;
secret:微信申請已存在的應用密匙;
code:調(diào)用上面一個接口自動返回的臨時票據(jù)。
grant_type:寫authorization_code
返回參數(shù)介紹
示例:
{
"access_token":"ACCESS_TOKEN",
"expires_in":7200,
"refresh_token":"REFRESH_TOKEN",
"openid":"OPENID",
"scope":"SCOPE"
}access_token:接口調(diào)用憑證
expires_in:access_token接口調(diào)用憑證超時時間,單位(秒)
refresh_token: 用戶刷新access_token
openid:授權用戶唯一標識(常用)
scope:用戶授權的作用域
4.調(diào)用接口根據(jù)access_token和openid獲取個人用戶信息
調(diào)用接口:
http請求方式: GET
https://api.weixin.qq.com/sns/userinfo?access_token=ACCESS_TOKEN&openid=OPENID
access_token:上個接口調(diào)用后返回的調(diào)用憑證
openid:上個接口獲取的授權用戶唯一標識返回參數(shù)介紹
示例;
{
"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"
}openid:授權用戶唯一標識
nickname:普通用戶昵稱
sex:普通用戶性別,1為男性,2為女性
province:普通用戶個人資料填寫的省份
city:普通用戶個人資料填寫的城市
country:國家,如中國為CN
headimgurl:用戶頭像,最后一個數(shù)值代表正方形頭像大?。ㄓ?、46、64、96、132數(shù)值可選,0代表640*640正方形頭像),用戶沒有頭像時該項為空
privilege:用戶特權信息,json數(shù)組,如微信沃卡用戶為(chinaunicom)
unionid:用戶統(tǒng)一標識。針對一個微信開放平臺帳號下的應用,同一用戶的unionid是唯一的。
三.代碼實現(xiàn):
1.創(chuàng)建相關工具類
封裝的幾個基礎類
a. access_token封裝基礎類
public class Token {
private String openid; //授權用戶唯一標識
private String accessToken; //接口調(diào)用憑證
private Integer ExpiresIn; //access_token接口調(diào)用憑證超時時間,單位(秒)
public String getOpenid() {
return openid;
}
public void setOpenid(String openid) {
this.openid = openid;
}
public String getAccessToken() {
return accessToken;
}
public void setAccessToken(String accessToken) {
this.accessToken = accessToken;
}
public Integer getExpiresIn() {
return ExpiresIn;
}
public void setExpiresIn(Integer expiresIn) {
ExpiresIn = expiresIn;
}b. 根據(jù)openid獲取用戶信息封裝成基礎類
public class WechatUserInfo {
private String unionid; //用戶唯一標識
private String nickname; //昵稱
private String headimgurl; //頭像地址
private String subscribe; // 用戶是否訂閱該公眾號標識,值為0時,代表此用戶沒有關注該公眾號,拉取不到其余信息。 1 用戶已經(jīng)綁定公眾號
public String getUnionid() {
return unionid;
}
public void setUnionid(String unionid) {
this.unionid = unionid;
}
public String getNickname() {
return nickname;
}
public void setNickname(String nickname) {
this.nickname = nickname;
}
public String getHeadimgurl() {
return headimgurl;
}
public void setHeadimgurl(String headimgurl) {
this.headimgurl = headimgurl;
}
public String getSubscribe() {
return subscribe;
}
public void setSubscribe(String subscribe) {
this.subscribe = subscribe;
}工具類
a. urlEncodeUTF8工具類(用于將掃描二維碼后重定向的資源url進行編碼)
public static String urlEncodeUTF8(String source){
String result = source;
try {
result = java.net.URLEncoder.encode(source,"utf-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return result;
}b. httpsRequest工具類(用于處理微信的獲取openid和用戶信息的接口的請求調(diào)用,返回相應的數(shù)據(jù))
/**
* 發(fā)送https請求
* @param requestUrl 請求地址
* @param requestMethod 請求方式(GET、POST)
* @param outputStr 提交的數(shù)據(jù)
* @return 返回微信服務器響應的信息
*/
public static String httpsRequest(String requestUrl, String requestMethod, String outputStr) {
try {
// 創(chuàng)建SSLContext對象,并使用我們指定的信任管理器初始化
TrustManager[] tm = { new MyX509TrustManager() };
SSLContext sslContext = SSLContext.getInstance("SSL", "SunJSSE");
sslContext.init(null, tm, new java.security.SecureRandom());
// 從上述SSLContext對象中得到SSLSocketFactory對象
SSLSocketFactory ssf = sslContext.getSocketFactory();
URL url = new URL(requestUrl);
HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();
conn.setSSLSocketFactory(ssf);
conn.setDoOutput(true);
conn.setDoInput(true);
conn.setUseCaches(false);
// 設置請求方式(GET/POST)
conn.setRequestMethod(requestMethod);
conn.setRequestProperty("content-type", "application/x-www-form-urlencoded");
// 當outputStr不為null時向輸出流寫數(shù)據(jù)
if (null != outputStr) {
OutputStream outputStream = conn.getOutputStream();
// 注意編碼格式
outputStream.write(outputStr.getBytes("UTF-8"));
outputStream.close();
}
// 從輸入流讀取返回內(nèi)容
InputStream inputStream = conn.getInputStream();
InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "utf-8");
BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
String str = null;
StringBuffer buffer = new StringBuffer();
while ((str = bufferedReader.readLine()) != null) {
buffer.append(str);
}
// 釋放資源
bufferedReader.close();
inputStreamReader.close();
inputStream.close();
inputStream = null;
conn.disconnect();
return buffer.toString();
} catch (ConnectException ce) {
log.error("連接超時:{}", ce);
} catch (Exception e) {
log.error("https請求異常:{}", e);
}
return null;
}
c. 獲取openid等信息的方法
public static Token getTokenWithOpenid(String appid, String appsecret, String code) {
String findAccessTokenUrl = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code";
Token token = null;
String requestUrl = findAccessTokenUrl.replace("APPID", appid).replace("SECRET", appsecret).replace("CODE", code);// 發(fā)起GET請求獲取憑證
JSONObject jsonObject = JSONObject.fromObject(httpsRequest(requestUrl, "GET", null));
if (null != jsonObject) {
try {
token = new Token();
token.setOpenid(jsonObject.getString("openid"));
token.setAccessToken(jsonObject.getString("access_token"));
token.setExpiresIn(jsonObject.getInt("expires_in"));
} catch (JSONException e) {
token = null;
// 獲取token失敗
log.error("獲取token失敗 errcode:{} errmsg:{}", jsonObject.getInt("errcode"), jsonObject.getString("errmsg"));
}
}
return token;
}d. 根據(jù)openid獲取用戶信息的方法
public static WechatUserInfo getUserinfo(String access_token, String openid) {
WechatUserInfo wxuse = new WechatUserInfo();
String findUseinfo = "https://api.weixin.qq.com/sns/userinfo?access_token=ACCESS_TOKEN&openid=OPENID";
String requestUrl = findUseinfo.replace("ACCESS_TOKEN", access_token).replace("OPENID", openid);
JSONObject jsonObject = JSONObject.fromObject(httpsRequest(requestUrl, "GET", null));
if (null != jsonObject) {
try {
wxuse.setNickname(jsonObject.getString("nickname"));
wxuse.setHeadimgurl(jsonObject.getString("headimgurl"));
wxuse.setUnionid(jsonObject.getString("unionid"));
} catch (JSONException e) {
e.printStackTrace();
}
}
return wxuse;
}操作:
a. 跳轉至登錄授權頁面(頁面出現(xiàn)二維碼)
public String weChatLanded(){
String requestUrl = "https://open.weixin.qq.com/connect/qrconnect?appid=APPID&redirect_uri=REDIRECT_URI&response_type=code&scope=SCOPE&state=STATE#wechat_redirect";
String loginAppid = "wxea43f181e32e8df0"; //微信申請的appid
String loginRedirectUrl = "http://www.dhdzp.com/weChatLogin_epf.action";//調(diào)用微信接口后返回的資源名
String loginScope = "snsapi_login";//寫死
redirectURL = requestUrl.replace("APPID", loginAppid).replace("REDIRECT_URI", CommonUtil.urlEncodeUTF8(loginRedirectUrl)).replace("SCOPE", loginScope);
return SUCCESS;
}b. 授權成功后:
@SuppressWarnings("static-access")
public String weChatLogin_epf(){
//通過code獲取access_token
String loginAppid = "wxea43f181e32e8df0";
String loginSecrect = "4721e5f744e6c0f3c4094b25449ee7e3";
Token tokenWithOpenid = CommonUtil.getTokenWithOpenid(loginAppid, loginSecrect,code);
String openid = tokenWithOpenid.getOpenid();
String access_token = tokenWithOpenid.getAccessToken();
//通過access_token調(diào)用接口
WechatUserInfo wxuse = CommonUtil.getUserinfo(access_token, openid);
return SUCCESS;
}到此這篇關于java實現(xiàn)微信掃碼登錄第三方網(wǎng)站功能(原理和代碼)的文章就介紹到這了,更多相關java微信第三方登錄內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
- Java后端接入微信小程序登錄功能(登錄流程)
- 微信小程序微信登錄的實現(xiàn)方法詳解(JAVA后臺)
- 詳解java實現(xiàn)簡單掃碼登錄功能(模仿微信網(wǎng)頁版掃碼)
- Java中基于Shiro,JWT實現(xiàn)微信小程序登錄完整例子及實現(xiàn)過程
- 使用weixin-java-tools完成微信授權登錄、微信支付的示例
- java實現(xiàn)微信小程序登錄態(tài)維護的示例代碼
- 第三方網(wǎng)站微信登錄java代碼實現(xiàn)
- java實現(xiàn) 微博登錄、微信登錄、qq登錄實現(xiàn)代碼
- Java實現(xiàn)微信登錄并獲取用戶信息功能(開發(fā)流程)
相關文章
教你在一分鐘之內(nèi)理解Java Lambda表達式并學會使用
今天給大家?guī)У奈恼率荍ava8新特性的相關知識,文章圍繞著如何在一分鐘之內(nèi)理解Java Lambda表達式并學會使用展開,文中有非常詳細的介紹,需要的朋友可以參考下2021-06-06
jstl之map,list訪問遍歷以及el表達式map取值的實現(xiàn)
下面小編就為大家?guī)硪黄猨stl之map,list訪問遍歷以及el表達式map取值的實現(xiàn)。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2017-03-03

