Play 2.6 OAuth的使用

27 篇文章 2 订阅
3 篇文章 0 订阅

OAuth

https://playframework.com/documentation/2.6.x/JavaOAuth

OAuth是一个发布和交互受保护数据的简单方法。这是一种更加安全的访问方式。举个例子,你可以去获取用户在Twitter上的数据。

OAuth有两个版本,1.02.0。第二个版本在不使用类库的情况下也很容易实现。因此Play只对1.0版本进行了支持。

使用

添加依赖

libraryDependencies ++= Seq(
  ws
)

需要的信息

OAuth需要你在服务提供商进行注册。确保检查你的回调URL,当不匹配是服务提供商有可能会拒绝你的调用。当在本地工作时,可以使用/etc/hosts/来伪造一个本地机器的域名

服务提供商会提供:
- Application ID
- Secret key
- Request Token URL
- Access Token URL
- Authorize URL

认证流程

大部分流程都会由Play类库来完成
1. 从服务端获取request token(在服务端到服务端的调用中)
2. 将用户重定向到服务提供商,这里用户会对你的应用进行授权
3. 服务提供商会将用户重定向返回,并提供一个verifier
4. 根据verifier,交换request token和access token
access token可以传递给任何需要获取保护数据的请求。

可以在The OAuth Bible获取更多细节。

Example

conf/routers

GET     /twitter/homeTimeline controllers.Twitter.homeTimeline()
GET     /twitter/auth         controllers.Twitter.auth()

controller

import play.libs.oauth.OAuth;
import play.libs.oauth.OAuth.ConsumerKey;
import play.libs.oauth.OAuth.OAuthCalculator;
import play.libs.oauth.OAuth.RequestToken;
import play.libs.oauth.OAuth.ServiceInfo;
import play.libs.ws.WSClient;
import play.mvc.Controller;
import play.mvc.Result;

import com.google.common.base.Strings;

import javax.inject.Inject;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CompletionStage;

public class Twitter extends Controller {
    static final ConsumerKey KEY = new ConsumerKey("...", "...");

    private static final ServiceInfo SERVICE_INFO =
        new ServiceInfo("https://api.twitter.com/oauth/request_token",
            "https://api.twitter.com/oauth/access_token",
            "https://api.twitter.com/oauth/authorize",
            KEY);

    private static final OAuth TWITTER = new OAuth(SERVICE_INFO);

    private final WSClient ws;

    @Inject
    public Twitter(WSClient ws) {
        this.ws = ws;
    }

    public CompletionStage<Result> homeTimeline() {
        Optional<RequestToken> sessionTokenPair = getSessionTokenPair();
        if (sessionTokenPair.isPresent()) {
            return ws.url("https://api.twitter.com/1.1/statuses/home_timeline.json")
                    .sign(new OAuthCalculator(Twitter.KEY, sessionTokenPair.get()))
                    .get()
                    .thenApply(result -> ok(result.asJson()));
        }
        return CompletableFuture.completedFuture(redirect(routes.Twitter.auth()));
    }

    public Result auth() {
        String verifier = request().getQueryString("oauth_verifier");
        if (Strings.isNullOrEmpty(verifier)) {
            String url = routes.Twitter.auth().absoluteURL(request());
            RequestToken requestToken = TWITTER.retrieveRequestToken(url);
            saveSessionTokenPair(requestToken);
            return redirect(TWITTER.redirectUrl(requestToken.token));
        } else {
            RequestToken requestToken = getSessionTokenPair().get();
            RequestToken accessToken = TWITTER.retrieveAccessToken(requestToken, verifier);
            saveSessionTokenPair(accessToken);
            return redirect(routes.Twitter.homeTimeline());
        }
    }

    private void saveSessionTokenPair(RequestToken requestToken) {
        session("token", requestToken.token);
        session("secret", requestToken.secret);
    }

    private Optional<RequestToken> getSessionTokenPair() {
        if (session().containsKey("token")) {
            return Optional.ofNullable(new RequestToken(session("token"), session("secret")));
        }
        return Optional.empty();
    }

}
OAuth不能抵御任何MITM攻击(https://en.wikipedia.org/wiki/Man-in-the-middle_attack)。这个例子中将token和secret保存到会话cookie中,通过play.http.session.secure=true配置来启用https来获取最好的保护。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值