使用Angular进行Steam身份验证

时间:2017-12-25 19:31:32

标签: angular authentication passport.js steam-web-api

我正在尝试使用Angular主页中的Steam进行身份验证,但每当我点击按钮(其中show_base()事件指向(click)中的login()功能)时,被重定向到Steam页面,当前页面刷新,没有任何反应。

这是服务器端代码:

AppComponent

这是'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

两台服务器都在运行(Angular和Node)。

修改:我添加了按钮而非链接,日志显示Same-origin policy出错。

4 个答案:

答案 0 :(得分:4)

简单地说,您无法将Angular服务重定向到后端=> steam =>后端回调网址。您必须将用户重定向到那里。

所以不要再调用authService.login(),而是添加直接链接,就像其他地方所说的那样。我没有在您的后端代码中看到第一个链接,但前端代码在SteamStrategy文档中建议/auth/steam

所以,第1步是这样的:

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

(您希望稍后从environment或某些此类网址获取该网址。)

现在发生了什么:

  1. 浏览器转到localhost:3000/auth/steam
  2. 节点将浏览器重定向到steam openId
  3. Steam,在成功登录和授权授权后,重定向回http://localhost:3000/auth/steam/return
  4. 接下来会发生什么?

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

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

    (在这里使用HashLocationStrategy,这样你就可以清楚地看到我在哪里重定向你了。)

    • 现在,Angular中的/authcallback路径可能会再次直接命中端点,以获取身份验证数据,然后再进行重定向。

    备选方案:

    现在,最后一部分可以采用不同的方式。你可以做一些事情,比如从节点重定向到索引或原始路由(你可以将它们添加为params等)。然后,有一个Angular服务,如果有auth数据,总是用后端检查。

    或者你可以让你的节点后端在Angular的index.html或你正在使用的任何页面中嵌入信息。你知道,老式的服务器端可能会在一个脚本标签中注入数据,例如ejsjade。它会更快,但我仍然不会盲目地相信客户端(或服务器),并会仔细检查,可能在后台。

答案 1 :(得分:1)

您在代码中执行的操作会向您自己的服务器调用GET请求。我根本看不到任何页面重定向。

如果您想将用户重定向到外部网站,您需要将用户发送到那里:

来自HTML文件:

<a href="http://example.com">Link to steam</a>

从您的组件.ts文件:

window.location.href = 'http://www.example.com'

如果您想将用户重定向到您网站上的其他页面,则需要使用Angular路由器:

来自HTML文件:

<a routerLink="/component-one">Component One</a>

从您的组件.ts文件:

this.router.navigate(['/component-one']);

所以你的组件现在变成了:

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

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css'],
  providers: [ AuthenticationService ] // This should be provided by the module, not the component
})
export class AppComponent {

  constructor(private authService: AuthenticationService, private router: Router) { }

  login(): void {
    this.authService.login().subscribe(data => {
      alert(data);
      this.router.navigate('/to-some-page');
    });
  }

}

使用简单的Google search可以找到更多示例,如下所示 https://coryrylan.com/blog/introduction-to-angular-routing

答案 2 :(得分:1)

据我所知,你永远不会将用户引导到一个蒸汽页面。您对klong的评论:&#34;重定向是通过Passport&#34;完成的。这可能是,但您永远不会将用户发送到特定页面。您只是在前端制作GET请求表。

关于同源政策错误。我认为这是由Passport引起的,因为您在快速服务器上使用Cors。我认为最好的解决方案是创建一个简单的代理。如果您使用CLI,则可以使用this example

答案 3 :(得分:1)

首先,您不要发送登录请求来表达后端。您必须将您的登录请求发送到steam oidc授权端点。看看Steam说的话:

  

使用OpenID时,用户从第三方网站的Web浏览器开始。当用户希望使用OpenID登录/链接他们的帐户到该网站时,该站点会将用户引导至Steam社区网站上的登录表单。用户输入Steam登录凭据后,用户的Web浏览器将自动重定向回第三方网站,并在返回URL后附加一些其他OpenID特定数据。然后,站点的OpenID库可以使用此数据来验证并获取用户的SteamID。

它被称为Oidc,幸运的是,Angular有两个好的库。 This (Recommended)This

您的快速服务器需要做的是在请求之前验证从角客户端收到的令牌。我对express不是很熟悉,但我确信至少有几个库可以验证令牌。

此外,您还需要对此主题进行更多研究。