我正在尝试从 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。)
现在发生了什么:
- 浏览器转到
localhost:3000/auth/steam
- Node 将浏览器重定向到 steam openId
- Steam,在成功登录和授权后,重定向回
http://localhost:3000/auth/steam/return
接下来会发生什么?
- 好吧,首先,将 Passport 策略中的配置文件数据保存到用户的配置文件中,或者至少保存到用户的 session 中。
然后,将用户重定向回 Angular 应用。像这样:
res.redirect('/public/#/authcallback
)`
(在这里使用 HashLocationStrategy 这样您就可以清楚地看到我将您重定向到哪里。)
- 现在,您在 Angular 中的
/authcallback
路由可能应该再次直接访问端点,以获取身份验证数据,然后再进行自己的重定向。
备选方案:
现在,最后一部分可以用不同的方式完成。您可以做一些事情,比如从节点重定向回索引或任何原始路由(您可以将它们添加为参数等)。然后,有一个 Angular 服务,它总是检查后端是否有授权数据。
或者您可以让您的节点后端嵌入 Angular 的index.html
或您正在使用的任何页面中的信息。您知道,老式的服务器端可能会在脚本标记中注入(inject)数据,例如 ejs
或 jade
。它会更快,但我仍然不会在客户端(或服务器)上盲目地信任它,并且会仔细检查,也许在后台。
关于angular - 使用 Angular 进行 Steam 身份验证,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47971478/