使用Angular进行Steam身份验证 [英] Steam authentication with Angular

查看:152
本文介绍了使用Angular进行Steam身份验证的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试从Angular主页中的Steam进行身份验证,但是每当我单击按钮(具有(click)事件指向AppComponent中的login()函数的按钮)时,都没有被重定向到Steam页面,当前页面已刷新,没有任何反应.

I'm trying to do authentication with Steam from the home page in Angular but whenever I click on button (which has (click) event pointing at login() function in AppComponent), instead of being redirected to Steam page, current page is refreshed and nothing happens.

这是服务器端代码:

'use strict';

const express = require('express');
const app = express();
const server = require('http').createServer(app);
const io = require('socket.io').listen(server);
const jwt = require('express-jwt');
const cors = require('cors');
const passport = require('passport');
const SteamStrategy = require('passport-steam').Strategy;
const mongoose = require('mongoose');

app.use(cors());
mongoose.connect('mongodb://localhost:27017/database_test');

passport.serializeUser((user, done) => {
    done(null, user);
});

passport.deserializeUser((obj, done) => {
    done(null, obj);
});

passport.use(new SteamStrategy({
        returnURL: 'http://localhost:3000/auth/steam/return',
        realm: 'http://localhost:3000',
        apiKey: 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxx'
    }, 
    (identifier, profile, done) => {
        process.nextTick(() => {
            profile.identifier = identifier;
            return done(null, profile);
        });
    }
));

app.use(passport.initialize());
app.use(passport.session());

app.get('/auth/steam',
    passport.authenticate('steam', { failureRedirect: 'http://localhost:4200/home' }),
    (req, res) => {
        res.json({"success": true, "res": res});
    }
);

app.get('/auth/steam/return', 
    passport.authenticate('steam', { failureRedirect: 'http://localhost:4200/home' }),
    (req, res) => {
        res.json({"success": true, "res": res});
    }
);

server.listen(3000, () => {
    console.log('Backend listening on port 3000.');
});

这是AuthenticationService:

import { Injectable } from '@angular/core';
import { Http, Headers, RequestOptions } from '@angular/http';
import { Observable } from 'rxjs';
import { JwtHelper, tokenNotExpired } from 'angular2-jwt';
import 'rxjs/add/operator/map';

@Injectable()
export class AuthenticationService {

  domain = 'http://localhost:3000';

  constructor(private http: Http) { }

  login() {
    return this.http.get(this.domain + '/auth/steam').map(res => res.json());
  }

}

这是AppComponent:

import { Component } from '@angular/core';
import { AuthenticationService } from './authentication.service';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css'],
  providers: [ AuthenticationService ]
})
export class AppComponent {

  constructor(private authService: AuthenticationService) { }

  login(): void {
    this.authService.login().subscribe(data => {
      alert(data);
    });
  }

}

两个服务器都在运行(Angular和Node).

Both servers are running (Angular and Node).

我添加了按钮而不是链接,日志显示了同源政策.

I added button instead of link and log showed me there is an error with Same-origin policy.

推荐答案

简单地说,您无法将Angular服务重定向到backend => steam => backend回调URL.您必须将用户重定向到那里.

Simply said, you can't redirect your Angular service to your backend=>steam=>backend callback url. You have to redirect the user there.

因此,无需调用authService.login(),只需添加直接链接即可,如其他地方所述.我在您的后端代码中没有看到第一个链接,但是前端代码建议/auth/steam像SteamStrategy文档中的一样.

So instead of calling the authService.login(), just add a direct link, like said elsewhere. I don't see the first link in your backend code, but frontend code suggests /auth/steam like in SteamStrategy docs.

所以,第一步是这样的:

So, step 1 is this:

// change the login() method on AuthService
login() {
  window.location.href = "http://localhost:3000/auth/steam";
}

(您将要从environment或以后的URL中获取该URL.)

(You'll want to take that URL from environment or some such later on.)

现在会发生什么:

  1. 浏览器转到localhost:3000/auth/steam
  2. 节点将浏览器重定向到Steam openId
  3. 成功登录和授权后,Steam重定向回http://localhost:3000/auth/steam/return
  1. Browser goes to localhost:3000/auth/steam
  2. Node redirects the browser to steam openId
  3. Steam, on successfull login and auth grant, redirects back to http://localhost:3000/auth/steam/return

接下来会发生什么?

  • 首先,将Passport策略中的个人资料数据保存到用户的个人资料或至少保存到用户的会话中.
  • 然后,将用户重定向回Angular应用.像这样:

res.redirect('/public/#/authcallback)`

(在这里使用HashLocationStrategy,这样您就可以清楚地看到我将您重定向到的位置.)

(Using HashLocationStrategy here so you see clearly where I was redirecting you.)

  • 现在,您在Angular中的/authcallback路由可能应该再次直接打到端点,以获取auth数据,然后再进行自己的重定向.
  • Now, your /authcallback route in Angular should probably hit the endpoint directly once more, to get the auth data, before doing it's own redirects.

替代品:

现在,最后一部分可以用不同的方式完成.您可以执行类似的操作,例如从节点重定向回索引或原始路由(您可以将其添加为参数等).然后,有一个Angular服务,该服务总是 向后端进行检查,是否有身份验证数据.

Now, that last part could be done differently. You could do something like redirect from node back to index or to whatever the original route was (you could add those as params etc). Then, have an Angular service, that always checks back with backend if there is auth data.

或者您可以将节点后端嵌入到Angular index.html或您正在使用的任何页面中的信息.您知道,老式的服务器端注入数据可能是带有ejsjade之类的脚本标记.这样会更快,但是我仍然不会盲目地在客户端(或服务器)上信任它,并且可能会在后台进行仔细检查.

Or you could have your node backend embed the info in Angular's index.html or whatever page you're using. You know, old-school, server-side inject data in maybe a script tag with something like ejs or jade. It would be faster, but I'd still not trust it blindly on client (or server) and would double-check, maybe in background.

这篇关于使用Angular进行Steam身份验证的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆