我正在尝试使用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出错。
答案 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
或某些此类网址获取该网址。)
现在发生了什么:
localhost:3000/auth/steam
http://localhost:3000/auth/steam/return
接下来会发生什么?
然后,将用户重定向回Angular app 。像这样:
res.redirect('/public/#/authcallback
)`
(在这里使用HashLocationStrategy,这样你就可以清楚地看到我在哪里重定向你了。)
/authcallback
路径可能会再次直接命中端点,以获取身份验证数据,然后再进行重定向。备选方案:
现在,最后一部分可以采用不同的方式。你可以做一些事情,比如从节点重定向到索引或原始路由(你可以将它们添加为params等)。然后,有一个Angular服务,如果有auth数据,总是用后端检查。
或者你可以让你的节点后端在Angular的index.html
或你正在使用的任何页面中嵌入信息。你知道,老式的服务器端可能会在一个脚本标签中注入数据,例如ejs
或jade
。它会更快,但我仍然不会盲目地相信客户端(或服务器),并会仔细检查,可能在后台。
答案 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不是很熟悉,但我确信至少有几个库可以验证令牌。
此外,您还需要对此主题进行更多研究。