使用Angular进行Steam身份验证

Nik*_*ola 6 authentication steam-web-api passport.js angular

我正在尝试从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.');
});
Run Code Online (Sandbox Code Playgroud)

这是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());
  }

}
Run Code Online (Sandbox Code Playgroud)

这是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);
    });
  }

}
Run Code Online (Sandbox Code Playgroud)

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

编辑:我添加了按钮而不是链接,日志显示我有同源策略的错误.

Zla*_*tko 5

简而言之,您无法将Angular服务重定向到backend => steam => backend回调URL。您必须在那里重定向用户。

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

因此,第一步是这样的:

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

(您以后将希望使用该URL environment或其他类似的URL 。)

现在会发生什么:

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

接下来发生什么?

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

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

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

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

备择方案:

现在,最后一部分可以不同地完成。您可以执行从节点重定向回索引或任何原始路由的操作(可以将其添加为params等)。然后,使用Angular服务,该服务始终向后端检查是否有身份验证数据。

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


klo*_*onq 1

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

如果您想将用户重定向到外部网站,您需要将用户发送到那里,可以执行以下任一操作:

来自 HTML 文件:

<a href="http://example.com">Link to steam</a>
Run Code Online (Sandbox Code Playgroud)

从您的组件 .ts 文件中:

window.location.href = 'http://www.example.com'
Run Code Online (Sandbox Code Playgroud)

如果您想将用户重定向到网站上的另一个页面,您需要使用 Angular Router:

来自 HTML 文件:

<a routerLink="/component-one">Component One</a>
Run Code Online (Sandbox Code Playgroud)

从您的组件 .ts 文件中:

this.router.navigate(['/component-one']);
Run Code Online (Sandbox Code Playgroud)

所以你的组件现在变成:

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');
    });
  }

}
Run Code Online (Sandbox Code Playgroud)

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