1. 程式人生 > >微信公眾號 授權登入 JAVA

微信公眾號 授權登入 JAVA

微信授權登入 java
首先 騰訊那麼大的公司 文件寫的那麼low 微信那麼火 demo寫的那麼差 我就想說一句 
微信簡直就是在歧視Java  

我這邊自己整合了下 微信支付和微信登入 java的程式碼  我打包出來了

不是讓你們直接使用的 是需要你們自己看看 借鑑的

http://download.csdn.net/download/qq_36020545/10129501

微信開發文件 官網:https://mp.weixin.qq.com/wiki
網頁版的微信登入

獲取APPID和AppSecret

我講一下我專案的流程

1.從前臺預設發起靜默授權
2.然後回撥地址是後臺處理方法 會自動帶有引數進入後臺  微信的那邊回撥會帶有code和state   我給出我的案例  : http://ghs.daivd.com/auth?code=XZXXXXXX&state=123 這是個GET請求
3.回撥到我們後臺方法 然後擷取code 然後通過code獲取使用者基礎資訊 我們主要需要就是 openid 和 使用者access_token
4.獲取我們公眾號token(因為獲取公眾號token有限制 最好是存在快取當彙總) 然後結合我們獲取到的使用者openid 來判斷使用者是否有關注我們公眾號 如果沒有我們就返回微信公眾號關注頁面 如果我們就可以進行獲取使用者資訊 然後存在我們資料中
5.然後返回我們前臺頁面

一.授權

微信有兩種網頁授權 
第一種是靜默授權:不會給使用者任何提示直接返回使用者code 但是如果使用者內有關注我們的公眾號那麼我們就沒有辦法拿到使用者很全的資訊
1、以snsapi_base為scope發起的網頁授權,是用來獲取進入頁面的使用者的openid的,並且是靜默授權並自動跳轉到回撥頁的。使用者感知的就是直接進入了回撥頁(往往是業務頁面)

第二種是手動授權:會給使用者彈出頁面卻要使用者點選確認,使用者點選後我們就能拿到使用者的資訊
2、以snsapi_userinfo為scope發起的網頁授權,是用來獲取使用者的基本資訊的。但這種授權需要使用者手動同意,並且由於使用者同意過,所以無須關注,就可在授權後獲取該使用者的基本資訊。 

下面是例子 注意是GET請求
https://open.weixin.qq.com/connect/oauth2/authorize?
appid=XXXXX 這個是appid 可以在你微信公眾平臺中的 基礎配置中找到 
&
redirect_uri=這裡填寫的是回撥地址 也就是微信登入後 返回訪問的地址 一般會填寫後臺地址 因為回撥是會帶有code值然後後臺可以通過code拿到使用者access_token  *重點是你的回撥地址需要使用urlEncode進行連線處理 直接百度urlEncode 有網頁版幫忙處理
&
response_type=code 這個是返回型別 不要改 返回型別,請填寫code
&
scope=這裡填寫登入類別 也就是我們上面說的 靜默授權或者是手動授權 snsapi_base(靜默)/snsapi_userinfo(手動)
&
state=123  我們可以自定義引數 重定向後會帶上state引數,可以填寫a-zA-Z0-9的引數值,最多128位元組
#wechat_redirect 這個是微信必填引數 不能改變


下面是給出的案例

靜默 https://open.weixin.qq.com/connect/oauth2/authorize?appid=XXXXXX&redirect_uri=http%3a%2f%2fghs.david.com%2fauth&response_type=code&scope=snsapi_base&state=STATE#wechat_redirect


手動 https://open.weixin.qq.com/connect/oauth2/authorize?appid=XXXXXX&redirect_uri=http%3a%2f%2fghs.david.com%2fauth&response_type=code&scope=snsapi_userinfo&state=STATE#wechat_redirect

這兩個就是從前臺發起的授權請求  

二.回撥方法
通過我們填寫的回撥url他會進入我們後臺回撥方法

		public void weixinLogin(HttpServletRequest request,HttpServletResponse response) throws Exception {


        Map<String, String[]> params = request.getParameterMap();//針對get獲取get引數
        String[] codes = params.get("code");//拿到的code的值
        String code = codes[0];//code
		
		
		//這一步就是拼寫微信api請求地址並 通過微信的appid 和 微信公眾號的AppSecret 以及我們獲取到的針對使用者授權回撥的code 拿到 這個使用者的 openid和access_token
		String requestUrl = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=APPSECRET&code=CODE&grant_type=authorization_code".replace("APPID", 填寫微信APPID).replace("APPSECRET", 填寫微信公眾號的AppSecret).replace("CODE", code);
		String requestResult = HttpTookit.doGet(requestUrl);//我們需要自己寫或者在網上找一個 doGet 方法 傳送doGet請求 
        JSONObject getCodeResultJson = JSON.parseObject(requestResult);//把請求成功後的結果轉換成JSON物件
		if(getCodeResultJson == null || getCodeResultJson.getInteger("errcode") != null || getCodeResultJson.getString("openid") == null) {
            throw 這裡需要拋異常 如果返回值沒有 或者 出現錯誤返回errcode 或者 沒有拿到openid
        }
		String openid = getCodeResultJson.getString("openid");//拿到openid
		
		
		//我們需要獲取當前公眾號通用的access_token 和使用者的access_token是不一樣的
		//這裡我為了讓大家可以方便就沒有寫太複雜  因為微信他那邊獲取微信公眾號的通用access_token每天只能取2000次 每次token有效期是7200S 所以在自己動手寫最好放在快取中 我的專案放在redis中
		String requestUrl = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET".replace("APPID", 填寫微信APPID).replace("APPSECRET", 填寫微信公眾號的AppSecret); 
		String requestResult = HttpTookit.doGet(requestUrl); 
		JSONObject weixinToken = JSON.parseObject(requestResult);
		if(jsonObject == null){
			throw 這裡需要拋異常 獲取我們公眾號token失敗
		}
		String wxgzhToken =  accessToken.setToken(jsonObject.getString("access_token"));
		
		//這裡是獲取使用者在我們公眾裡面的資訊 如果沒有關注公眾號那麼就沒有辦法獲取詳細資訊 引數需要 微信公眾號通用token 和 使用者openid
		String requestUrl = "https://api.weixin.qq.com/cgi-bin/user/info?access_token=ACCESS_TOKEN&openid=OPENID&lang=zh_CN".replace("ACCESS_TOKEN", wxgzhToken).replace("OPENID", openid);
		String requestResult = HttpTookit.doGet(requestUrl); 
		JSONObject user = JSON.parseObject(requestResult);
		if(user == null || user.getInteger("errcode") != null ) {
			拋異常
		}
		
		Integer subscribe = user.getInteger("subscribe");//是否有關注我們公眾號
        if(subscribe == 0){//沒有關注我們公眾號
              response.sendRedirect("https://mp.weixin.qq.com/mp/profile_ext?action=home&__biz=MzIyNTc1MDQ2Mw==&scene=110#wechat_redirect");//跳到我們公眾號關注頁面 url地址需要你麼你自己去擷取
        }else{//關注了
             如果關注了
			 user中就會有詳細的資訊 我們既可以把這些資訊存在我們的資料庫中
			 然後跳轉到我們前臺頁面
        }
	
    }





這裡講一下這些apiurl返回的json

//獲取微信公眾號的通用access_token每天只能取2000次 每次token有效期是7200S 所以在自己動手寫最好放在快取中 我的專案放在redis中
//grant_type=獲取access_token填寫client_credential(必填) appid=填寫我們的appid(必填)  secret=填寫微信公眾號的AppSecret(必填) 
String requestUrl = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET".replace("APPID", 填寫微信APPID).replace("APPSECRET", 填寫微信公眾號的AppSecret); 
返回的JSON
{
"access_token":"ACCESS_TOKEN",//獲取到的憑證
"expires_in":7200 //憑證有效時間,單位:秒
}


//通過微信的appid 和 微信公眾號的AppSecret 以及我們獲取到的針對使用者授權回撥的code 拿到 這個使用者的 openid和access_token  appid=填寫我們的appid(必填)  secret=填寫微信公眾號的AppSecret(必填) grant_type=獲取access_token填寫authorization_code(必填)
String requestUrl = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=APPSECRET&code=CODE&grant_type=authorization_code".replace("APPID", 填寫微信APPID).replace("APPSECRET", 填寫微信公眾號的AppSecret).replace("CODE", code);
返回的JSON
{
"access_token":"ACCESS_TOKEN",   //使用者的access_token  官網解釋:網頁授權介面呼叫憑證,注意:此access_token與基礎支援的access_token不同
"expires_in":7200,    //access_token介面呼叫憑證超時時間,單位(秒)
"refresh_token":"REFRESH_TOKEN",    //使用者重新整理access_token(不知道)
"openid":"OPENID",    //使用者唯一標識,請注意,在未關注公眾號時,使用者訪問公眾號的網頁,也會產生一個使用者和公眾號唯一的OpenID (這個是重點 我們主要就是為了這個)
"scope":"SCOPE" //使用者授權的作用域,使用逗號(,)分隔(不知道)





//這裡是獲取使用者在我們公眾裡面的資訊 如果沒有關注公眾號那麼就沒有辦法獲取詳細資訊 引數需要 微信公眾號通用token 和 使用者openid 還有 lang =返回國家地區語言版本,zh_CN 簡體,zh_TW 繁體,en 英語
String requestUrl = "https://api.weixin.qq.com/cgi-bin/user/info?access_token=ACCESS_TOKEN&openid=OPENID&lang=zh_CN".replace("ACCESS_TOKEN", wxgzhToken).replace("OPENID", openid);
返回的JSON
{
    "subscribe": 1, //使用者是否訂閱該公眾號標識,值為0時,代表此使用者沒有關注該公眾號,拉取不到其餘資訊。
    "openid": "o6_bmjrPTlm6_2sgVt7hMZOPfL2M", //使用者的標識,對當前公眾號唯一
    "nickname": "Band", //使用者的暱稱
    "sex": 1, //使用者的性別,值為1時是男性,值為2時是女性,值為0時是未知
    "language": "zh_CN", //使用者的語言,簡體中文為zh_CN
    "city": "廣州", //使用者所在城市
    "province": "廣東", //使用者所在省份
    "country": "中國", //使用者所在國家
    "headimgurl":    "http://wx.qlogo.cn/mmopen/g3MonUZtNHkdmzicIlibx6iaFqAc56vxLSUfpb6n5WKSYVY0ChQKkiaJSgQ1dZuTOgvLLrhJbERQQ4eMsv84eavHiaiceqxibJxCfHe/0", //使用者頭像,最後一個數值代表正方形頭像大小(有0、46、64、96、132數值可選,0代表640*640正方形頭像),使用者沒有頭像時該項為空。若使用者更換頭像,原有頭像URL將失效
   "subscribe_time": 1382694957,//使用者關注時間,為時間戳。如果使用者曾多次關注,則取最後關注時間
   "unionid": " o6_bmasdasdsad6_2sgVt7hMZOPfL", // 只有在使用者將公眾號繫結到微信開放平臺帳號後,才會出現該欄位 (這個我也沒有搞清楚)
   "remark": "",//公眾號運營者對粉絲的備註,公眾號運營者可在微信公眾平臺使用者管理介面對粉絲新增備註
   "groupid": 0 //使用者所在的分組ID
}

希望我的分享可以幫助到大家避免一些坑