[英]OAuth with Ionic 3 and Rails (devise_token_auth)
我正在使用Ruby on Rails后端构建Ionic 3(Angular 4)应用程序。
我正在使用angular2-token
和devise_token_auth
进行用户和API调用身份验证,这两个功能可以一起使用。
它们的工作方式很简单:它们在每个API调用标头上创建并跟踪一些字段(即auth-token
, client
, uid
和expiry
)。
它可以完美地使用电子邮件注册/登录。 我现在想为我的应用程序实现Instagram OAuth登录,这在常规的Angular Web应用程序中应该是InAppBrowser
事,但是在Ionic中,我无法控制路由或URL,因此可以采取的策略是启动InAppBrowser
并在其上设置事件以检测其何时到达我的API回调URL。
基本上:
myapi.com/auth/instagram
内部InAppBrowser
InAppBrowser
加载myapi.com/omniauth/instagram/callback?code=57...
,我检测到它。 至此,我的后端已经根据Instagram数据成功创建了一个用户。
问题是,我不知道如何在客户端进行处理。
当我使用电子邮件/密码登录时, angular2-token
作用是POST /auth/sign_in
,请求标头包含auth_token
和东西,然后对其进行处理并存储以供后续调用。 现在,OAuth流位于InAppBrowser
实例中,不受我的控制。
我真的很沮丧,因为我看到OAuth流程在后端运行,而前端部分可以在InAppBrowser之外的常规Web应用程序上轻松完成。
我将复制一些前端和后端代码以提供更多上下文,希望这有助于理解问题。
处理OAuth流程的前端:
public logInWithInstagram(): Promise<any>{
var callbackURL = environment.token_auth_config.apiBase + "/omniauth/instagram/callback";
var oauthURL = environment.token_auth_config.apiBase + "/auth/instagram";
var parsedResponse = {};
return new Promise(function(resolve, reject) {
var browserRef = window.cordova.InAppBrowser.open(oauthURL, "_blank", "location=no,clearsessioncache=yes,clearcache=yes");
browserRef.addEventListener("loadstart", (event) => {
if ((event.url).indexOf(callbackURL) === 0) {
browserRef.removeEventListener("exit", (event) => {});
browserRef.close();
var responseParameters = ((event.url).split("?")[1]).split("&");
var parsedResponse = {};
for (var i = 0; i < responseParameters.length; i++) {
parsedResponse[responseParameters[i].split("=")[0]] = responseParameters[i].split("=")[1];
}
if (typeof(parsedResponse["code"]) !== 'undefined' && parsedResponse["code"] !== null) {
// Successful Instagram OAuth, backend has already created the user by now
resolve(parsedResponse);
} else {
reject("Problem authenticating");
}
}
});
browserRef.addEventListener("exit", function(event) {
reject("The sign in flow was canceled");
});
});
}
后端,用于创建用户并处理回调URL的部分:
class Users::OmniauthCallbacksController < DeviseTokenAuth::OmniauthCallbacksController
def redirect_callbacks
@user = User.from_omniauth(request.env["omniauth.auth"])
if @user.persisted?
sign_in_and_redirect @user
else
session["devise.instagram_data"] = request.env["omniauth.auth"]
redirect_to new_user_registration_url
end
end
def failure
redirect_to root_path
end
end
任何帮助,策略或想法,我都将不胜感激。 非常感谢你!
Angular2令牌位于Alpha中,并且尚未处理返回给inAppBrowser的凭据。
我们最终分叉了该项目,并在angular2-token包中添加了一个逻辑分支来解决该问题。
仍然有点麻烦(例如,oAuthLogin尚未返回可观察到的消息,您必须轮询登录成功),但是它可以工作。
如果您想尝试一下,该软件包就在这里: https : //github.com/chadnaylor/angular2-token-ionic3
除了离子逻辑外,它与angular2-token基本相同。 希望我们将其清理干净后再将其合并。
如果您想自己进行调整,则我们更改的内容如下所示:
browser.on('loadstop').subscribe((ev: InAppBrowserEvent) => {
if (0 === ev.url.indexOf(this.atOptions.oAuthBrowserCallback)) {
browser.executeScript({code: "requestCredentials();"})
.then((credentials) => {
// alert(JSON.stringify(credentials[0]));
this.getAuthDataFromPostMessage(credentials[0]);
let pollerObserv = Observable.interval(400);
let pollerSubscription = pollerObserv.subscribe(() => {
if(this.userSignedIn()){
pollerSubscription.unsubscribe();
browser.close();
}
});
})
}
});
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.