15 September 2012
這篇文章主要是教學如何使用Google OAuth,
然後利用OAuth給的token去存取gmail帳號!


至於OAuth是甚麼就不多做介紹...
可以去WIKI看  http://en.wikipedia.org/wiki/OAuth
簡言之,是一個公開的標準認證機制!


而使用Google OAuth大概可以分為下列步驟:

  1. 在Google Console註冊一個Application 
  2. 取得Google回傳的Access Token(基本上到這步驟,代表登入成功)
  3. 傳送Access Token至某隻Google API取得Google的資料


【在Google Console註冊一個Application 】

在這步驟要先去Google Console頁面上去註冊一個application,
然後再為這個application申請一組client id。


點進去以後大概會見到下圖,
見到下圖(圖一)以後,就先點選下圖(圖一)中左邊的API Access,
注意! 一定要點! 點了以後,下圖(圖一)中右邊的區塊才會出現Create an OAuth 2.0 client ID的按鈕!
出現右邊的區塊以後,就點選Create an OAuth 2.0 client ID的按鈕!
圖一


如果你曾經註冊過一個application,那就不會看到上圖(圖一)的頁面,
但大同小異! 還是會有一個按鈕(Create another client ID...)
點選以後就會直接見到圖三,而不會見到下圖(圖二)

而如果沒有註冊過application的,就會見到下圖(圖二)。
下面的頁面主要輸入產品名稱即可! 
輸入以後就按下下圖(圖二)Next

圖二



點選上圖(圖二)中的Next以後,就會見到下圖(圖三),
這個頁面很重要!
這頁面要填寫你的Domain Name以及接收access token的頁面!
但預設的狀況你只能填寫Domain Name,如下圖(圖三)的紅色框框!
而藍色框框中的URI(https://www.example.com/oauth2callback) 就是接收access token的頁面!
當然,如果你想要填寫自己接收access token的頁面,也是可以自己改!
只要點選下圖(圖三)中的綠色框框(more options)即可!
點選以後就會見到下圖(圖四)
圖三


下圖(圖四)就是點選上圖(圖三)的more options才會看到的頁面。
你可以看到下圖(圖四)有個紅色框框,在那裏面就可以修改自己接收access token的頁面!
填寫完成以後,記得按下圖片中(圖三或圖四)下面的Create client ID按鈕!
點了才會完成。

圖四

完成以後,會看到下圖(圖五)的頁面!
這頁面也很重要!!!!
因為Google 會給你一組Client ID和Client Sercet,
這兩個資訊在後面進行auth的時候會用到!
圖五


【取得Google回傳的access token 】

在這步驟就要進行coding了。


先大致說明一下流程,可以參考下圖。
流程一:
  User會先點選一個URL,
  而這URL會連結至Google 登入頁面,
  User得先輸入帳號&密碼進行登入,
  (這過程都是在Google Server上進行,我們的Server端是不會取得到User的密碼的)
流程二:
  如果User輸入的帳號密碼正確,那麼Google就會把Access Token傳回去至我們的Server,
流程三:
  發一個request給Google API,
  把Google回傳給我們的token傳至Google API以存取我們想要存取的資訊!
流程三:
  接收Google 回傳的資訊



恩,接著要開始寫code了。
如上面所述,我們要有一個接收access token的頁面!
以及一個讓User點擊的連結(這個連結會redirect至Google登入頁面)
而這個連結也會帶著幾個參數!
如下


參數說明:
scope:意思是你要利用這個token存取那些Google API,這邊我們要存取USER資訊,所以就是如上述sample所示。
state:這是一個optional 的參數,可以填任意字串
redirecut_uri:這個參數很重要,意思是如果user輸入帳密正確以後,Google要redirect至哪一個接收access_token的頁面,基本上這個參數的value就是如上圖中(圖四)你所填的值!
response_type:這個參數的value一定要填寫code!code的意思是我們接收的頁面是用server-side接收response! 預設還有另一個value(token),但token代表的是我們是利用Javascript去進行接收!但此sample是用JSP/Servlet的Servlet來接收!所以就填寫code!
client_id:就填寫自己的client_id!!!

基本上user點選上述的Link以後,
會見到登入頁面!
登入完成以後就會redirect至oauth2callback去了!
並且會reponse一個參數給我們!參數名稱為code

而這邊我已JSP/Servlet為例!
所以我先建立一個名字為oauth2callback的Servlet,
這個Servlet會用來接收Google回傳給我們的參數(code),
然後這支Servlet會再發出一個request,並且帶著參數code。
然後Google就會回傳給我們access_token

@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {

// Google取得access_token的url
URL urlObtainToken = new URL("https://accounts.google.com/o/oauth2/token");
HttpURLConnection connectionObtainToken = (HttpURLConnection) urlObtainToken.openConnection();

// 設定此connection使用POST
connectionObtainToken.setRequestMethod("POST");
connectionObtainToken.setDoOutput(true);

// 開始傳送參數
OutputStreamWriter writer = new OutputStreamWriter(connectionObtainToken.getOutputStream());
writer.write("code="+req.getParameter("code")+"&"); // 取得Google回傳的參數code
writer.write("client_id=xxxxxxxxxxxxxxxxxx&xxxx&"); // 這裡請將xxxx替換成自己的client_id
writer.write("client_secret=xxxxxxxxxxxxxxxxxxx&"); // 這裡請將xxxx替換成自己的client_serect
writer.write("redirect_uri=xxxxxxxxxxxxxxxxxxxx&"); // 這裡請將xxxx替換成自己的redirect_uri
writer.write("grant_type=authorization_code");
writer.close();

// 如果認證成功
if (connectionObtainToken.getResponseCode() == HttpURLConnection.HTTP_OK){
StringBuilder sbLines = new StringBuilder("");

// 取得Google回傳的資料(JSON格式)
BufferedReader reader =
new BufferedReader(new InputStreamReader(connectionObtainToken.getInputStream(),"utf-8"));
String strLine = "";
while((strLine=reader.readLine())!=null){
sbLines.append(strLine);
}

try {
// 把上面取回來的資料,放進JSONObject中,以方便我們直接存取到想要的參數
JSONObject jo = new JSONObject(sbLines.toString());

// 印出Google回傳的access token
resp.getWriter().println(jo.getString("access_token"));
} catch (JSONException e) {
e.printStackTrace();
}
}
}







如果完成上述步驟,基本上就代表user的帳號密碼是正確!
那意思就是說,如果你的網站想要導入讓user使用Google帳號進行登入的話,
完成上述步驟就OK了!

當然,如果你想要取得更進一步的user資訊,
只要利用上述得到的access_token,然後把這個token帶給Google API即可獲得資訊!
例如想要得到User的email,即可利用下列的API,
https://www.googleapis.com/oauth2/v1/userinfo
但是要餵給他參數!
CODE如下:


URL urUserInfo =   
new URL("https://www.googleapis.com/oauth2/v1/userinfo?access_token="+jo.getString("access_token"));
HttpURLConnection connObtainUserInfo = (HttpURLConnection) urUserInfo.openConnection();


//如果認證成功
if (connObtainUserInfo.getResponseCode() == HttpURLConnection.HTTP_OK){
StringBuilder sbLines = new StringBuilder("");

// 取得Google回傳的資料(JSON格式)
BufferedReader reader =
new BufferedReader(new InputStreamReader(connObtainUserInfo.getInputStream(),"utf-8"));
String strLine = "";
while((strLine=reader.readLine())!=null){
sbLines.append(strLine);
}

try {
// 把上面取回來的資料,放進JSONObject中,以方便我們直接存取到想要的參數
JSONObject jo = new JSONObject(sbLines.toString());

// 印出Google回傳的"emailtoken
resp.getWriter().println(jo.getString("email"));

} catch (JSONException e) {
e.printStackTrace();
}
}








blog comments powered by Disqus