1. 程式人生 > >微信授權登入_程式碼可以直接使用

微信授權登入_程式碼可以直接使用

微信網頁授權登陸,官方文件:https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140842

直接上程式碼,相關注意事項在程式碼中已用TODO標記

Controller層

package com.controller;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.service.WXService;

/**
 * 微信授權登入流程
 * 1,建立授權URL
 * 2,使用者授權
 * 3,微信回撥
 * 4,自身業務處理
 */
public class WXController {

	private WXService wXService; // 微信Service
	
	/**
	 * 建立授權登入URL
	 * 
	 * @return
	 * @throws Exception 
	 */
	public String createAuthenUrl() throws Exception {
		return wXService.createAuthorizationURL();
	}
	
	/**
	 * 獲取授權認證
	 * 
	 * @param request
	 * @param response
	 */
	public void getAuthorization(HttpServletRequest request, HttpServletResponse response) {
		// 獲取微信授權端返回的code
		String code = request.getParameter("code");
		// 獲取微信授權端返回的status
		String state = request.getParameter("state");
		
		// TODO 自身業務邏輯
	}
	
	/**
	 * 頁面輪詢
	 * 
	 * @param request
	 * @return
	 */
	public String checkedState(HttpServletRequest request) {
		String state = request.getParameter("state");
		// TODO 自身業務邏輯
		return "";
	}
}

Service層
package com.service;

import java.util.UUID;

import com.send.SendHttpRequest;

public class WXService {
	// 公眾號的唯一標識
	private static String APP_ID = "";
	// 公眾號的APPSecret
	private static String APP_SECRET = "";
	// 使用者同意授權URL(對urlEncode之後)
	private static String REDIRECT_URL = "";
	// 使用者同意授權URL
	private static String AUTHORIZATION_URL = "https://open.weixin.qq.com/connect/oauth2/authorize";
	// 獲取access_tokenURL
	private static String GET_TOKEN_URL = "https://api.weixin.qq.com/sns/oauth2/access_token";
	// 拉取使用者資訊URL
	private static String GET_USER_INFO_URL = "https://api.weixin.qq.com/sns/userinfo";
	
	/**
	 * 獲取微信普通的token用於呼叫微信一般的介面
	 * 
	 * @return
	 * @throws Exception
	 */
	public String getCommonToken() throws Exception {
		// 獲取token的url
		String url = "https://api.weixin.qq.com/cgi-bin/token";
		// 引數
		String param = "grant_type=client_credential&appid=" +
				APP_ID + "&secret=" + APP_SECRET;
		// 傳送請求並獲取資訊
		String result = SendHttpRequest.sendGetRequest(url, param);
		// 校驗是否請求成功
		if (result == null) {
			throw new Exception("獲取token失敗");
		}
		if (result.contains("errcode")) {
			throw new Exception(result);
		}
		// TODO 返回值資訊參照官方文件
		// TODO 返回值中的token需要儲存在本地,token過期後再獲取.注意:本地的過期時間要早於微信返回的過期時間
		return result;
	}
	

	/**
	 * 建立授權登入URL
	 * 
	 * 1,獲取普通token
	 * 2,生成微信使用者登入授權URL
	 * 3,將長連結轉成短連結(這步可以省略,但不建議。原因:長連結生成的二維碼非常密集,導致效能較差的手機,掃碼時間過長或者無法識別)
	 * 4,返回state和short_url
	 * 
	 * @return
	 * @throws Exception
	 */
	public String createAuthorizationURL() throws Exception {
		// 普通token
		String commontoken = "";
		// state(根據業務需求而定,這裡用於頁面輪詢)
		String state = UUID.randomUUID().toString().replace("-", "");
		// 微信使用者登入授權URL
		String longUrl = AUTHORIZATION_URL +"?appid=" + APP_ID + "&redirect_uri=" + REDIRECT_URL
					+ "&response_type=code&scope=snsapi_userinfo&state=" + state + "#wechat_redirect";
		// 請求路徑(將長連結轉成短連結)
		String url = "https://api.weixin.qq.com/cgi-bin/shorturl?access_token=" + commontoken;
		// 請求引數
		String param = "{"
				+ "\"action\":\"long2short\","
				+ "\"long_url\":\"" + longUrl +"\""
				+ "}";
		// TODO 返回值資訊參照官方文件
		// 傳送請求並獲取結果(將長連結轉成短連結)
		String result = SendHttpRequest.sendPostRequest(url, param);
		if (!result.contains("short_url")) {
			throw new Exception(result);
		}
		// TODO 根據業務需求儲存state和state過期時間(微信回撥時會返回該引數;頁面輪詢時,需要校對state)
		// TODO 在result中獲取short_url
		String short_url = "";
		String resultMap = "{"
				+ "\"state\":" + "\"" + state +"\"," 
				+ "\"shortURL\":" + "\"" + short_url + "\""
				+ "}";
		return resultMap;
	}
	
	/**
	 * 用code換取access_token相關資訊
	 * 
	 * @param code 用於換取access_token
	 * @return
	 * @throws Exception
	 */
	public String getAccessToken(String code) throws Exception {
		// 建立請求引數
		String param = "appid=" + APP_ID +"&secret=" + APP_SECRET + "&code=" + code
				+ "&grant_type=authorization_code";
		// 傳送請求並獲取響應資訊
		String result = SendHttpRequest.sendGetRequest(GET_TOKEN_URL, param);
		// 校驗是否請求成功
		if (result == null) {
			throw new Exception("獲取token失敗");
		}
		if (result.contains("errcode")) {
			throw new Exception(result);
		}
		// TODO 返回值資訊參照官方文件
		return result;
	}
	
	/**
	 * 用accessToken和openid拉取使用者資訊
	 * 
	 * @param accessToken
	 * @param openid
	 * @return
	 * @throws Exception
	 */
	public String getUserInfo(String accessToken, String openid) throws Exception {
		// 建立請求引數
		String param = "access_token=" + accessToken + "&openid=" + openid
				+ "&lang=zh_CN ";
		// 傳送請求並獲取響應資訊
		String result = SendHttpRequest.sendGetRequest(GET_USER_INFO_URL, param);
		// 校驗是否請求成功
		if (result == null) {
			throw new Exception("獲取userInfo失敗");
		}
		if (result.contains("errcode")) {
			throw new Exception(result);
		}
		// TODO 返回值資訊參照官方文件
		return result;
	}
}

SendHttpRequest類
package com.send;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.URL;
import java.net.URLConnection;

/**
 * 傳送http請求
 *
 */
public class SendHttpRequest {
	
	/**
	 * 傳送GET請求
	 * 
	 * @param url 請求地址
	 * @param param 請求引數(格式:key1=value1&key2=value2&key3=value3)
	 * @return
	 * @throws Exception 
	 */
	public static String sendGetRequest(String url, String param) throws Exception {
		String result = "";
		BufferedReader in = null;
		try {
			// 拼接URL和引數
			String urlAndParam = url + "?" + param;
			// 建立URL物件
			URL realUrl = new URL(urlAndParam);
			// 開啟URL的連結
			URLConnection conn = realUrl.openConnection();
			// 設定Head資訊
			conn.setRequestProperty("accept", "*/*");
			conn.setRequestProperty("connection", "Keep-Alive");
			// 建立連結
			conn.connect();
			// 定義 BufferedReader輸入流來讀取URL的響應
			in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
			// 臨時引數
			String line;
			// 獲取響應結果
			while ((line = in.readLine()) != null) {
				result += line;
			}
		}catch(Exception e) {
			throw new Exception("請求失敗");
		}finally {
			try {
				if (in != null) {
					in.close();
				}
			} catch (Exception e2) {
				throw new Exception("請求失敗");
			}
		}
		return result;
	}
	
	/**
	 * 傳送POST請求
	 * 
	 * @param url 請求地址
	 * @param param 請求引數[格式:key1=value1&key2=value2 || JSON.toString()]
	 * @return
	 * @throws Exception 
	 */
	public static String sendPostRequest(String url, String param) throws Exception {
		String result = "";
		PrintWriter out = null;
		BufferedReader in = null;
		try {
			// 建立URL物件
			URL realUrl = new URL(url);
			// 開啟URL的連結
			URLConnection conn = realUrl.openConnection();
			// 設定Head資訊
			conn.setRequestProperty("accept", "*/*");
			conn.setRequestProperty("connection", "Keep-Alive");
			// POST請求設定
			conn.setDoOutput(true);
            conn.setDoInput(true);
			// 獲取輸出流
            out = new PrintWriter(conn.getOutputStream());
            // 傳送請求引數
            out.print(param);
            // flush輸出流的緩衝
            out.flush();
            // 獲取輸入流,讀取響應請求
            in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
            // 臨時引數
         	String line;
         	// 獲取響應結果
         	while ((line = in.readLine()) != null) {
         		result += line;
         	}
		}catch(Exception e) {
			throw new Exception("請求失敗");
		}finally {
			try {
				if (in != null) {
					in.close();
				}
			} catch (Exception e2) {
				throw new Exception("請求失敗");
			}
		}
		return result;
	}
	
	public static void main(String[] args) throws Exception {
		System.out.println(sendPostRequest("http://www.baidu.com", ""));
	}

}

寫的不嚴謹的地方,請指出哈!先謝謝指教