Hướng dẫn sử dụng Scribe OAuth Java API với Google OAuth 2
1. Vấn đề với Google Oauth1a
Có một vấn đề với Google OAuth 1a. Bắt đầu từ ngày 20-04-2015, google chính thức không hỗ trợ giao thức OAuth 1 nữa. Nếu bạn đang sử dụng Scribe Java API để làm việc với Google OAuth 1.0, bạn bắt buộc phải thay đổi code của mình.
Trong tài liệu này tôi sẽ hướng dẫn bạn sử dụng Scribe Java API làm việc với Google OAuth 2.0
Trong tài liệu này tôi sẽ hướng dẫn bạn sử dụng Scribe Java API làm việc với Google OAuth 2.0
2. Tạo ứng dụng trên Google Developers Console
Trong lần đầu tiên, bạn chưa có một Project nào, bạn cần phải tạo nó, thông thường bạn nên đặt tên của Project theo tên của Website của bạn (Không bắt buộc).
Đặt tên project: ExampleWebsite
Project của bạn đã được tạo ra:
Vào mục "APIs and auth/Consent screen" để khai báo một Product Name.
Tạo mới Client ID:
Trong trường hợp bạn sử dụng OAuth2.0 trên ứng dụng web bạn phải tạo ClientID cho ứng dụng web. Đồng thời khai báo đường dẫn redirect (Đường dẫn sẽ redirect tới sau khi người dùng đăng nhập vào tài khoản google của họ và cho phép ứng dụng của bạn kết nối với Google OAuth).
ClientID đã được tạo ra, trong đó có 2 thông tin quan trọng nhất là Client ID và Client Secret, bạn cần nó trong code Java (Sẽ được minh họa trong ví dụ dưới đây).
Chú ý: Bạn có thể tạo nhiều ClientID cho các ứng dụng khác nhau của bạn.
3. Tạo nhanh Project & khai báo thư viện Scribe Java API
- File/New/Others
Project của bạn đã được tạo ra.
Cấu hình Maven sử dụng Scribe Java API:
pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.o7planning</groupId>
<artifactId>ScribeGoogleOAuth2</artifactId>
<version>0.0.1-SNAPSHOT</version>
<dependencies>
<!-- http://mvnrepository.com/artifact/org.scribe/scribe -->
<dependency>
<groupId>org.scribe</groupId>
<artifactId>scribe</artifactId>
<version>1.3.7</version>
</dependency>
</dependencies>
</project>
4. Code Project
Scribe Java API là một API giúp bạn làm việc với OAuth dễ dàng hơn, nó ẩn đi sự khác biệt giữa các nhà cung cấp dịch vụ OAuth (Google, yahoo, facebook,..), và hỗ trợ OAuth 1a, OAuth 2.0
Ví dụ để làm việc với LinkIn, code của bạn là:
OAuthService service = new ServiceBuilder()
.provider(LinkedInApi.class)
.apiKey(YOUR_API_KEY)
.apiSecret(YOUR_API_SECRET)
.build();
Để làm việc với Google OAuth 1a code của bạn là:
OAuthService service = new ServiceBuilder()
.provider(GoogleApi.class)
.apiKey(YOUR_API_KEY)
.apiSecret(YOUR_API_SECRET)
.build();
Scribe Java API đã có sẵn các API cho các nhà cung cấp khác nhau:
- FacebookApi
- GoogleApi
- FoursquareApi
- Foursquare2Api
- YahooApi
- TwitterApi
- ....
Thật đáng tiếc là GooleApi chỉ sử dụng được cho Google OAuth 1, không sử dụng được cho Google OAuth 2.0, và bạn cũng không tìm thấy lớp Google2Api trong thư viện của Scribe 1.3.7 (Có thể vì lý do bản quyền).
Vì vậy trong project của mình bạn cần tạo class Google2Api, và chú ý, nó phải nằm trong package org.scribe.builder.api:
Vì vậy trong project của mình bạn cần tạo class Google2Api, và chú ý, nó phải nằm trong package org.scribe.builder.api:
Google2Api.java
package org.scribe.builder.api;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.scribe.exceptions.OAuthException;
import org.scribe.extractors.AccessTokenExtractor;
import org.scribe.model.OAuthConfig;
import org.scribe.model.OAuthConstants;
import org.scribe.model.OAuthRequest;
import org.scribe.model.Response;
import org.scribe.model.Token;
import org.scribe.model.Verb;
import org.scribe.model.Verifier;
import org.scribe.oauth.OAuth20ServiceImpl;
import org.scribe.oauth.OAuthService;
import org.scribe.utils.OAuthEncoder;
import org.scribe.utils.Preconditions;
/**
* Google OAuth2.0 Released under the same license as scribe (MIT License)
*
* @author yincrash
*
*/
public class Google2Api extends DefaultApi20 {
private static final String AUTHORIZE_URL = "https://accounts.google.com/o/oauth2/auth?response_type=code&client_id=%s&redirect_uri=%s";
private static final String SCOPED_AUTHORIZE_URL = AUTHORIZE_URL
+ "&scope=%s";
@Override
public String getAccessTokenEndpoint() {
return "https://accounts.google.com/o/oauth2/token";
}
@Override
public AccessTokenExtractor getAccessTokenExtractor() {
return new AccessTokenExtractor() {
@Override
public Token extract(String response) {
Preconditions
.checkEmptyString(response,
"Response body is incorrect. Can't extract a token from an empty string");
Matcher matcher = Pattern.compile(
"\"access_token\" : \"([^&\"]+)\"").matcher(response);
if (matcher.find()) {
String token = OAuthEncoder.decode(matcher.group(1));
return new Token(token, "", response);
} else {
throw new OAuthException(
"Response body is incorrect. Can't extract a token from this: '"
+ response + "'", null);
}
}
};
}
@Override
public String getAuthorizationUrl(OAuthConfig config) {
// Append scope if present
if (config.hasScope()) {
return String.format(SCOPED_AUTHORIZE_URL, config.getApiKey(),
OAuthEncoder.encode(config.getCallback()),
OAuthEncoder.encode(config.getScope()));
} else {
return String.format(AUTHORIZE_URL, config.getApiKey(),
OAuthEncoder.encode(config.getCallback()));
}
}
@Override
public Verb getAccessTokenVerb() {
return Verb.POST;
}
@Override
public OAuthService createService(OAuthConfig config) {
return new GoogleOAuth2Service(this, config);
}
private class GoogleOAuth2Service extends OAuth20ServiceImpl {
private static final String GRANT_TYPE_AUTHORIZATION_CODE = "authorization_code";
private static final String GRANT_TYPE = "grant_type";
private DefaultApi20 api;
private OAuthConfig config;
public GoogleOAuth2Service(DefaultApi20 api, OAuthConfig config) {
super(api, config);
this.api = api;
this.config = config;
}
@Override
public Token getAccessToken(Token requestToken, Verifier verifier) {
OAuthRequest request = new OAuthRequest(api.getAccessTokenVerb(),
api.getAccessTokenEndpoint());
switch (api.getAccessTokenVerb()) {
case POST:
request.addBodyParameter(OAuthConstants.CLIENT_ID,
config.getApiKey());
request.addBodyParameter(OAuthConstants.CLIENT_SECRET,
config.getApiSecret());
request.addBodyParameter(OAuthConstants.CODE,
verifier.getValue());
request.addBodyParameter(OAuthConstants.REDIRECT_URI,
config.getCallback());
request.addBodyParameter(GRANT_TYPE,
GRANT_TYPE_AUTHORIZATION_CODE);
break;
case GET:
default:
request.addQuerystringParameter(OAuthConstants.CLIENT_ID,
config.getApiKey());
request.addQuerystringParameter(OAuthConstants.CLIENT_SECRET,
config.getApiSecret());
request.addQuerystringParameter(OAuthConstants.CODE,
verifier.getValue());
request.addQuerystringParameter(OAuthConstants.REDIRECT_URI,
config.getCallback());
if (config.hasScope())
request.addQuerystringParameter(OAuthConstants.SCOPE,
config.getScope());
}
Response response = request.send();
return api.getAccessTokenExtractor().extract(response.getBody());
}
}
}
Tạo một class MyConstants lưu trữ Google Client ID và Client Secret mà bạn đã tạo ra trước đó trên Google Developers Console.
MyConstants.java
package org.o7planning.tutorial.scribegoogle;
public class MyConstants {
// Client ID
public static final String GOOGLE_CLIENT_ID = "884814088321-lfgc199ui38csrv75bf2fr3etksv0kpm.apps.googleusercontent.com";
// Client Secret
public static final String GOOGLE_CLIENT_SECRET = "yNHBZRDB-ThCIRa29pNJEyh-";
// Redirect URI
public static final String GOOGLE_REDIRECT_URL = "https://examplewebsite.com/mypath/oauth2callback";
}
Google2Example.java
package org.o7planning.tutorial.scribegoogle.test;
import java.util.Scanner;
import org.o7planning.tutorial.scribegoogle.MyConstants;
import org.scribe.builder.ServiceBuilder;
import org.scribe.builder.api.Google2Api;
import org.scribe.model.OAuthRequest;
import org.scribe.model.Response;
import org.scribe.model.Token;
import org.scribe.model.Verb;
import org.scribe.model.Verifier;
import org.scribe.oauth.OAuthService;
public class Google2Example {
private static final String NETWORK_NAME = "Google";
private static final String PROTECTED_RESOURCE_URL = "https://www.googleapis.com/oauth2/v2/userinfo?alt=json";
private static final String SCOPE = "https://mail.google.com/ https://www.googleapis.com/auth/userinfo.email";
private static final Token EMPTY_TOKEN = null;
public static void main(String[] args) {
String apiKey = MyConstants.GOOGLE_CLIENT_ID;
String apiSecret = MyConstants.GOOGLE_CLIENT_SECRET;
String callbackUrl = MyConstants.GOOGLE_REDIRECT_URL;
// Tạo OAuthService cho Google OAuth 2.0
OAuthService service = new ServiceBuilder().provider(Google2Api.class)
.apiKey(apiKey).apiSecret(apiSecret).callback(callbackUrl)
.scope(SCOPE).build();
Scanner in = new Scanner(System.in);
System.out.println("=== " + NETWORK_NAME + "'s OAuth Workflow ===");
System.out.println();
Verifier verifier = null;
Token accessToken = null;
// Obtain the Authorization URL
System.out.println("Fetching the Authorization URL...");
String authorizationUrl = service.getAuthorizationUrl(EMPTY_TOKEN);
System.out.println("Got the Authorization URL!");
System.out.println("Now go and authorize Scribe here:");
System.out.println();
// Copy URL này và chạy trên trình duyệt.
System.out.println(authorizationUrl);
System.out.println();
// Copy Authorization Code trên URL của trình duyệt và dán vào Console.
System.out.println("And paste the authorization code here");
System.out.print(">>");
verifier = new Verifier(in.nextLine());
System.out.println();
// Trade the Request Token and Verfier for the Access Token
System.out.println("Trading the Request Token for an Access Token...");
accessToken = service.getAccessToken(EMPTY_TOKEN, verifier);
System.out.println("Got the Access Token!");
System.out.println("(if your curious it looks like this: "
+ accessToken + " )");
System.out.println();
// Now let's go and ask for a protected resource!
System.out.println("Now we're going to access a protected resource...");
OAuthRequest request = new OAuthRequest(Verb.GET,
PROTECTED_RESOURCE_URL);
service.signRequest(accessToken, request);
Response response = request.send();
System.out.println("Got it! Lets see what we found...");
System.out.println();
System.out.println(response.getCode());
System.out.println(response.getBody());
System.out.println();
System.out
.println("Thats it man! Go and build something awesome with Scribe! :)");
in.close();
}
}
Chạy lớp Google2Example:
Copy URL như hình khoanh đỏ phía trên và chạy trên trình duyệt:
Sau đăng nhập vào tài khoản google, Google đòi hỏi User cho phép ứng dụng xem một số thông tin tài khoản. Nhấn vào Accept để cho phép.
Website sẽ chuyển hướng (redirect) tới Callback-URL, bao gồm cả mã truy cập, bạn cần copy mã này:
Copy mã và dán lên cửa sổ Java Console:
Bạn sẽ nhận được các thông tin người dùng:
Các thư viện mã nguồn mở Java
- Hướng dẫn và ví dụ Java JSON Processing API (JSONP)
- Hướng dẫn sử dụng Scribe OAuth Java API với Google OAuth 2
- Lấy thông tin phần cứng máy tính trong ứng dụng Java
- Restfb Java API cho Facebook
- Tạo Credentials cho Google Drive API
- Hướng dẫn sử dụng Java JDOM2 phân tích tài liệu XML
- Hướng dẫn và ví dụ Java XStream
- Hướng dẫn sử dụng Java Jsoup phân tích HTML
- Lấy thông tin địa lý dựa trên địa chỉ IP sử dụng GeoIP2 Java API
- Đọc Ghi file excel trong Java sử dụng Apache POI
- Khám phá Facebook Graph API
- Java Sejda WebP ImageIO chuyển đổi các định dạng ảnh sang WEBP
- Java JAVE Chuyển đổi audio và video sang định dạng mp3
- Thao tác với tập tin và thư mục trên Google Drive sử dụng Java
Show More