Приложение, над которым я работаю, имеет внешний интерфейс, который обслуживает SPA (React / React-Router) и API-интерфейс (node.js). Я должен получить полную реализацию входа в систему OpenIDConnect. Уже был частично настроен и "работает". Моя проблема в том, что мой SPA не знает, аутентифицирован ли он или нет. Я нашел другой пост, в котором кто-то предложил использовать React-Router onEnter
и создать функцию, которая просто запрашивает конечную точку, чтобы узнать, аутентифицирован ли пользователь, но onEnter
устарела; и предложенная замена для этого (поместите пользовательский код в render
prop), похоже, не работает ни с одной из моих библиотек http-запросов, потому что они все асинхронные.
Предлагаемая замена React-Router, которую я нашел
<Route
path="/content"
render={(props) => {
this.isAuthenticated() ?
(<ContentContainer {...props}/>):(<Redirect to="/somewhere/else" />)
}}
/>
Как я могу заменить исходную функциональность onEnter
или есть лучший способ обработки аутентификации? Я включил код для бэкэнда ниже на случай, если есть лучший способ.
BACKEND / API, который выполняет аутентификацию
app.use(function(req, res, next) {
res.header("Access-Control-Allow-Origin", config.frontEndUrl);
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
next();
});
app.use(cors(corsOptions));
app.use(cookieParser());
app.use(session({resave: 'true', saveUninitialized: 'true' , secret: 'keyboardsaff2'}));
app.use(passport.initialize());
app.use(passport.session());
app.use(bodyParser.urlencoded({extended:true}));
app.use(bodyParser.json());
process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0";
passport.serializeUser((user, done) => {
done(null, user);
});
passport.deserializeUser((obj, done) => {
done(null, obj);
});
var OpenIDConnectStrategy = require('passport-idaas-openidconnect').IDaaSOIDCStrategy;
var Strategy = new OpenIDConnectStrategy({
authorizationURL : config.authorization_url,
tokenURL : config.token_url,
clientID : config.client_id,
scope: 'openid',
response_type: 'code',
clientSecret : config.client_secret,
callbackURL : config.callback_url,
skipUserProfile: true,
issuer: config.issuer_id,
addCACert: true,
CACertPathList: []
},
(iss, sub, profile, accessToken, refreshToken, params, done) => {
process.nextTick(() => {
profile.accessToken = accessToken;
profile.refreshToken = refreshToken;
done(null, profile);
})
});
passport.use(Strategy);
app.get('/login', passport.authenticate('openidconnect', {}));
function ensureAuthenticated(req, res, next) {
if (!req.isAuthenticated()) {
req.session.originalUrl = req.originalUrl;
res.redirect('/login');
} else {
return next();
}
}
app.get('/auth/sso/callback', (req, res, next) => {
var redirectURL = req.session.originalUrl;
passport.authenticate('openidconnect', {
successRedirect: redirectURL,
failureRedirect: '/failure',
})(req,res,next);
});
app.get('/failure', (req, res) => {
res.send('login failed');
});
app.get('/authenticate', ensureAuthenticated, (req, res) => {
var claims = req.user['_json'];
res.redirect(req.query.redirectUrl+"?id="+req.user.id.toLowerCase()+(req.query.firstName?"&firstName="+req.query.firstName:"")+(req.query.lastName?"&lastName="+req.query.lastName:"")+(req.query.companyName?"&companyName="+req.query.companyName:"")+(req.query.role?"&role="+req.query.role:""));
});