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).
编辑:我添加了按钮而不是链接,日志显示我有同源策略的错误.
简而言之,您无法将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 。)
现在会发生什么:
localhost:3000/auth/steamhttp://localhost:3000/auth/steam/return接下来发生什么?
然后,将用户重定向回Angular app。像这样:
res.redirect('/public/#/authcallback)`
(在此处使用HashLocationStrategy,这样您就可以清楚地看到我将您重定向到的位置。)
/authcallback在Angular中的路由可能应该再次直接命中端点,以获取身份验证数据,然后再执行自己的重定向。备择方案:
现在,最后一部分可以不同地完成。您可以执行从节点重定向回索引或任何原始路由的操作(可以将其添加为params等)。然后,使用Angular服务,该服务始终向后端检查是否有身份验证数据。
或者,您可以让您的节点后端将信息嵌入到Angular index.html或您正在使用的任何页面中。您知道,老式的服务器端注入数据可能是带有ejs或的脚本标签jade。这样会更快,但是我仍然不会盲目地在客户端(或服务器)上信任它,并且可能会在后台进行仔细检查。
您在代码中所做的操作会调用对您自己的服务器的 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