我正在为我的angular 6 Web应用程序创建登录策略。用户单击登录按钮,它会触发对我的节点服务器上的localhost:3000 / login的HTTP请求。我正在使用okta作为身份验证者,并使用了护照oidc策略。如果我转到localhost:3000 / login,它将按预期执行重定向到okta登录门户的操作。当我从有角度的前端尝试时,会收到CORS错误。我已使用通配符启用Access-Control-Allow-Origin。
//app.js
require("dotenv").config();
const express = require("express");
const app = express();
const bodyParser = require("body-parser");
const routes = require("./routes/routes");
const mongoose = require("mongoose");
const casperRoutes = require("./routes/casper-routes");
const oktaRoutes = require("./routes/okta-routes");
const slackRoutes = require("./routes/slack-routes");
const session = require("express-session");
const passport = require("passport");
const OidcStrategy = require("passport-openidconnect").Strategy;
const oktaBaseAuth = process.env.OKTA_AUTH_URI;
mongoose
.connect(
"mongodb+srv://xxxxx",
{ useNewUrlParser: true }
)
.then(() => {
console.log("connected to database!");
})
.catch(() => {
console.log("connection failed");
});
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
app.use((req, res, next) => {
res.setHeader("Access-Control-Allow-Origin", "*");
res.setHeader(
"Access-Control-Allow-Headers",
"Origin, X-requested-With, Content-Type, Accept"
);
res.setHeader(
"Access-Control-Allow-Methods",
"GET, POST, PATCH, PUT, DELETE, OPTIONS, PUT"
);
next();
});
app.use(
session({
secret: "xxx",
resave: false,
saveUninitialized: true
})
);
app.use(passport.initialize());
app.use(passport.session());
passport.use(
"oidc",
new OidcStrategy(
{
issuer: oktaBaseAuth + "/oauth2/default",
authorizationURL: oktaBaseAuth + "/oauth2/default/v1/authorize",
tokenURL: oktaBaseAuth + "/oauth2/default/v1/token",
userInfoURL: oktaBaseAuth + "/oauth2/default/v1/userinfo",
clientID: process.env.OKTA_AUTH_CLIENT_ID,
clientSecret: process.env.OKTA_AUTH_CLIENT_SECRET,
callbackURL: 'http://localhost:3000/authorization-code/callback',
scope: "openid profile"
},
(issuer, sub, profile, accessToken, refreshToken, done) => {
return done(null, profile);
}
)
);
passport.serializeUser((user,next)=>{
next(null,user);
});
passport.deserializeUser((obj,next)=>{
next(null,obj);
});
app.use('/login', passport.authenticate('oidc'));
app.use('/authorization-code/callback',
passport.authenticate('oidc', {failureRedirect: '/error'}),
(req,res)=>{
res.redirect('/');
});
function checkLogged(req,res,next){
if (req.isAuthenticated()){
return next();
}
res.redirect('/login');
}
app.use("/api/casper",checkLogged, casperRoutes);
app.use("/api/data",checkLogged, routes);
app.use("/api/okta", checkLogged,oktaRoutes);
app.use("/api/slack", checkLogged, slackRoutes);
module.exports = app;
前端服务
import { HttpClient, HttpHeaders } from '@angular/common/http';
import { Subject, Observable } from "rxjs";
import * as OktaSignIn from "@okta/okta-signin-widget";
import { Injectable } from "@angular/core";
import { Router } from "@angular/router";
@Injectable({
providedIn: "root"
})
export class OktaService {
widget;
isAuthenticated = false;
user;
private headers = new HttpHeaders();
private authStatusListener = new Subject<boolean>();
constructor(private http: HttpClient, private router: Router) {}
loginUser(){
this.http.get('http://localhost:3000/login').subscribe(res=>console.log(res));
}
}
错误
Failed to load https://dev-795809.oktapreview.com/oauth2/default/v1/authorize?response_type=code&client_id=0oag898j7zj7j8jqw0h7&redirect_uri=http%3A%2F%2Flocalhost%3A3000%2Fauthorization-code%2Fcallback&scope=openid%20openid%20profile&state=rtFMOtsHHBOc90UcM3nLIz%2Fp: Redirect from 'https://dev-795809.oktapreview.com/oauth2/default/v1/authorize?response_type=code&client_id=0oag898j7zj7j8jqw0h7&redirect_uri=http%3A%2F%2Flocalhost%3A3000%2Fauthorization-code%2Fcallback&scope=openid%20openid%20profile&state=rtFMOtsHHBOc90UcM3nLIz%2Fp' to 'https://dev-795809.oktapreview.com/login/login.htm?fromURI=/oauth2/v1/authorize/redirect?okta_key=c8hyLEuNV3KeYJyLfw2EU9xDjqsqeSOLft2jLzh-07E' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'null' is therefore not allowed access.
我也在我的OKTA应用程序上启用了CORS。我在某处读到这可能是因为我无法使用通配符来解析授权数据的CORS。如何使用在不同端口上运行的有角度前端连接到后端进行登录?
答案 0 :(得分:0)
发生这种情况是因为您试图向后端发出XHR请求。如果您将其更改为重定向到后端,则应该可以使用。
loginUser() {
window.location.href = 'http://localhost:3000/login'
}
此方法的问题在于,成功登录后,很可能会将您重定向回Node应用程序,而不是Angular应用程序。您可以在Node应用程序中编写自定义代码,以在身份验证后重定向回引荐来源网址。我已经使用Spring Security做到了这一点,但是我不确定如何在Node上做到这一点。
另一种选择是使用我们的Angular SDK并在Angular应用中进行身份验证,然后将Node API设置为资源服务器,以简单地验证传入的访问令牌。