angular - 使用 Angular 进行 Steam 身份验证

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

我正在尝试从 Angular 的主页使用 Steam 进行身份验证,但是每当我点击按钮(它有 (click) 事件指向 login() AppComponent 中的函数),而不是被重定向到 Steam 页面,当前页面被刷新并且没有任何反应。

这是服务器端代码:

'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)。

编辑:我添加了按钮而不是链接,日志显示 Same-origin policy 有错误.

最佳答案

简单地说,你不能将你的 Angular 服务重定向到你的后端=>steam=>后端回调 url。您必须将用户重定向到那里。

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

所以,第 1 步是这样的:

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

(您需要从 environment 或稍后的一些类似的地方获取该 URL。)

现在发生了什么:

  1. 浏览器转到 localhost:3000/auth/steam
  2. Node 将浏览器重定向到 steam openId
  3. Steam,在成功登录和授权后,重定向回 http://localhost:3000/auth/steam/return

接下来会发生什么?

  • 好吧,首先,将 Passport 策略中的配置文件数据保存到用户的配置文件中,或者至少保存到用户的 session 中。
  • 然后,将用户重定向回 Angular 应用。像这样:

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

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

  • 现在,您在 Angular 中的 /authcallback 路由可能应该再次直接访问端点,以获取身份验证数据,然后再进行自己的重定向。

备选方案:

现在,最后一部分可以用不同的方式完成。您可以做一些事情,比如从节点重定向回索引或任何原始路由(您可以将它们添加为参数等)。然后,有一个 Angular 服务,它总是检查后端是否有授权数据。

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

关于angular - 使用 Angular 进行 Steam 身份验证,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47971478/

相关文章:

python - 如何使用 Python 进行用户身份验证 Azure DevOps

spring - 如何在Spring Security 3中设置用户角色?

node.js - 当用户处于事件状态时,req.session.user 被删除

使用类装饰器时需要 Angular4 core.es5.js 未捕获的反射元数据垫片

authentication - 限制特定仪表板中的某些 kibana 用户

javascript - passportjs 本地策略没有被调用

node.js - 是否有任何(简单的)方法可以将变量从 Express 传递到 Vue.js?

angular - BsDatepicker 没有出现在子组件中(ngx-bootstrap)

javascript - Angular/Firestore - 'Where' 查询返回错误 'property does not exist on type AngularFirestoreCollection'

node.js - 亚马逊认知 : How to implement Post Confirmation Trigger which works only after SignupConfirmation not after ForgotPassword/ResetPassword Confirmation