2017-12-25 122 views
6

Tôi đang cố gắng xác thực bằng Steam từ trang chủ trong Angular nhưng bất cứ khi nào tôi nhấp vào nút (có (click) sự kiện trỏ tại login() chức năng trong AppComponent), thay vì được chuyển hướng đến trang Steam, hiện tại trang được làm mới và không có gì xảy ra.Xác thực hơi nước với Angular

là Mã này server-side:

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

Đây là 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()); 
    } 

} 

Đây là 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); 
    }); 
    } 

} 

Cả hai máy chủ đang chạy (góc và Node).

Chỉnh sửa: Tôi đã thêm nút thay vì liên kết và nhật ký cho thấy tôi có lỗi với Same-origin policy.

+1

Chỉ muốn thêm, kudo để làm việc với Steam. Tôi chủ yếu là droning với các công cụ kinh doanh/công ty với Angular, và đánh giá lưu lượng truy cập StackOverflow, hầu hết những người khác đang có. Bạn đang đặc biệt trong việc làm một cái gì đó được, tôi giả định, liên quan đến game! Chúc may mắn cho bạn, thưa bạn, và có tất cả những niềm vui, và sau đó có một số niềm vui hơn cho phần còn lại của chúng tôi :) – Zlatko

Trả lời

1

Những gì bạn đang làm trong mã của mình gọi yêu cầu GET đến máy chủ của riêng bạn. Tôi không thấy bất kỳ chuyển hướng trang nào cả.

Nếu bạn muốn chuyển hướng người dùng đến một trang web bên ngoài bạn cần phải gửi cho người dùng ở đó, một trong hai:

Từ tập tin HTML:

<a href="http://example.com">Link to steam</a> 

Từ tập tin .ts thành phần của bạn:

window.location.href = 'http://www.example.com' 

Nếu bạn muốn chuyển hướng người dùng đến một trang khác trên trang web của bạn, yo u cần phải sử dụng Router góc:

Từ tập tin HTML:

<a routerLink="/component-one">Component One</a> 

Từ .ts thành phần tập tin của bạn:

this.router.navigate(['/component-one']); 

Vì vậy, bạn phần lúc này là:

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

} 

Bạn có thể tìm thêm các ví dụ khác với số đơn giản Google search, như số dưới đây https://coryrylan.com/blog/introduction-to-angular-routing

+0

Chuyển hướng được thực hiện thông qua phương thức '' 'authenticate''' của Passport một cách tự động. – Nikola

1

Theo tôi có thể thấy bạn không bao giờ hướng người dùng đến trang xông hơi. Bình luận của bạn để klong: "Chuyển hướng được thực hiện thông qua hộ chiếu". Điều này có thể, tuy nhiên bạn không bao giờ đưa bạn đến một trang cụ thể. Bạn chỉ cần tạo một biểu mẫu yêu cầu GET mà bạn đã đặt trước.

Giới thiệu về lỗi chính sách cùng nguồn gốc. Tôi cho rằng điều này là do Hộ chiếu bởi vì bạn sử dụng Cors trên máy chủ tốc hành của bạn. Tôi nghĩ giải pháp tốt nhất là tạo một proxy đơn giản. Nếu bạn sử dụng CLI, bạn có thể sử dụng this example.

1

Trước hết, bạn không gửi yêu cầu đăng nhập để thể hiện chương trình phụ trợ. Bạn phải gửi yêu cầu đăng nhập của bạn đến trạm cấp cứu oidc hơi nước.Xem những gì Steam nói:

Khi sử dụng OpenID, người dùng bắt đầu trong trình duyệt web tại trang web của bên thứ ba. Khi người dùng muốn đăng nhập/liên kết tài khoản của họ với trang web đó, bằng cách sử dụng OpenID, trang web sẽ hướng người dùng đến biểu mẫu đăng nhập trên trang web của Cộng đồng Steam. Khi người dùng đã nhập thông tin đăng nhập hơi của họ, trình duyệt web của người dùng sẽ tự động được chuyển hướng trở lại trang web của bên thứ ba với một số dữ liệu cụ thể OpenID bổ sung được thêm vào URL trả về. Thư viện OpenID của trang web sau đó có thể sử dụng dữ liệu này để xác minh và lấy SteamID của người dùng.

Nó được gọi là Oidc và may mắn là bạn có hai thư viện tốt cho Angular. This (Recommended)This.

Máy chủ tốc hành của bạn cần làm gì là xác thực mã thông báo đã nhận được từ ứng dụng khách góc của bạn trước khi yêu cầu. Tôi không quen thuộc lắm nhưng tôi chắc rằng có ít nhất một vài thư viện để bạn xác nhận mã thông báo.

Ngoài ra, bạn cần nghiên cứu thêm về chủ đề này.

2

Nói đơn giản, bạn không thể chuyển hướng dịch vụ Góc của bạn tới url phụ trợ => steam => url gọi lại phụ trợ của bạn. Bạn phải chuyển hướng người dùng ở đó.

Vì vậy, thay vì gọi số authService.login(), chỉ cần thêm liên kết trực tiếp, như được nói ở nơi khác. Tôi không thấy liên kết đầu tiên trong mã phụ trợ của bạn, nhưng mã lối vào gợi ý /auth/steam như trong tài liệu SteamStrategy.

Vì vậy, bước 1 là thế này:

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

(Bạn sẽ muốn lấy URL mà từ environment hoặc một số ví dụ sau này.)

gì xảy ra bây giờ:

  1. Trình duyệt truy cập vào localhost:3000/auth/steam
  2. Nút chuyển hướng trình duyệt tới hơi nước openId
  3. Hơi nước, khi đăng nhập thành công và cấp quyền xác thực, chuyển hướng trở lại http://localhost:3000/auth/steam/return

Điều gì xảy ra tiếp theo?

  • Trước tiên, hãy lưu dữ liệu hồ sơ đó trong chiến lược Hộ chiếu vào hồ sơ của người dùng hoặc ít nhất đến phiên của người dùng.
  • rồi, chuyển hướng người dùng quay lại ứng dụng Góc. Một cái gì đó như thế này:.

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

(Sử dụng HashLocationStrategy đây để bạn thấy rõ nơi tôi đang chuyển hướng bạn)

  • Bây giờ, /authcallback tuyến đường ở góc có lẽ nên nhấn điểm cuối trực tiếp một lần nữa, để lấy dữ liệu auth, trước khi thực hiện chuyển hướng riêng của nó.

Alternatives:

Bây giờ, đó là phần cuối cùng có thể được thực hiện khác nhau. Bạn có thể làm điều gì đó như chuyển hướng từ nút quay lại chỉ mục hoặc đến bất kỳ tuyến đường ban đầu nào (bạn có thể thêm chúng dưới dạng thông số, v.v.). Sau đó, có dịch vụ Góc, luôn luôn kiểm tra lại với chương trình phụ trợ nếu có dữ liệu xác thực.

Hoặc bạn có thể có nút phụ trợ nhúng thông tin trong Angular's index.html hoặc bất kỳ trang nào bạn đang sử dụng. Bạn biết đấy, trường học cũ, dữ liệu tiêm phía máy chủ có thể là một thẻ tập lệnh với một cái gì đó như ejs hoặc jade. Nó sẽ nhanh hơn, nhưng tôi vẫn không tin tưởng nó một cách mù quáng trên máy khách (hoặc máy chủ) và sẽ kiểm tra lại, có thể ở chế độ nền.

+1

Trả lời cũng giúp tôi. Được viết tốt, cảm ơn Zlatko. – filipbarak

Các vấn đề liên quan