Comments (34)
Sorry for the super late response! Had a busy start of the semester...
I have a working template for social providers via passport (Google, Github, etc.) which I use as a SSO option on an Angular application, in which further authentication is handled by using JWTs as described in the current Nest.js docs. I will try to at least show some material here!
I am also debating on writing a Medium post about Angular + OAuth2 SSO + Passport + JWTs + Nest.js. People interested in that?
from docs.nestjs.com.
The back-end part is live: https://medium.com/@nielsmeima/auth-in-nest-js-and-angular-463525b6e071
from docs.nestjs.com.
For those following/landing on this thread, there are a couple of recent documents that should help
- The authentication chapter was completely re-written (as of July 2019) with an end-to-end example
- A recent (July 2019) article on dev.to on sessions covers sessions and was reviewed by the Nest core team.
I'll keep this open for now as I'm not sure #1365, and #264 are addressed yet.
from docs.nestjs.com.
I'm new to Node.js, let alone NestJS, but, thanks to others who have added their samples here, I've published a blog post and GitHub repo to demonstrate OpenID Connect (OIDC) authentication using the OpenID Certified™ passport strategy "openid-client". I'm using Google as my Identity Provider but it works equally well with Keycloak, Okta, etc. I serve up a create-react-app-typescript front-end leveraging the session from express-session and storing the session in MongoDB.
from docs.nestjs.com.
I'm trying to get openid-client to work with nestjs/passport..... since, PassportStrategy needs in the constructor the full params (client_id, client_secret) but openid-client needs to call an "Issuer" promise first (discover)/method.... so anyone could please give some advices to continue.
- first aproach: returns "client" must be an instance of "openid-client"
import { Injectable } from "@nestjs/common";
import { PassportStrategy } from "@nestjs/passport";
import * as OpenIDClient from "openid-client"
@Injectable()
export class OpenIDStrategy extends PassportStrategy(OpenIDClient.Strategy, 'oidc') {
constructor() {
super({
client_id: process.env.APP_AUTH_CLIENT_ID,
client_secret: process.env.AUTH_CLIENT_SECRET,
callbackURL: process.env.APP_AUTH_REDIRECT_URI,
passReqToCallback: true,
scope: [
'openid',
]
})
}
validate(request: any, accessToken: string, refreshToken: string, profile, done: Function) {
return done(null, { ...profile, accessToken, refreshToken });
}
}
- Here's what I've got in express (currently working code)...
(...)
try {
trustIssuer = await OpenIDIssuer.discover(process.env.AUTH);
const client = new trustIssuer.Client({
client_id: process.env.APPLICATION_UID,
client_secret: process.env.SECRET
});
client.CLOCK_TOLERANCE = 10000000;
const params = {
redirect_uri: `${process.env.REDIRECT_URI}/auth/cb`,
scope: process.env.SCOPES
}
passport.use('oidc', new OpenIDStrategy({ client, params, passReqToCallback: false, usePKCE: false }, (tokenset, userinfo, done) => {
tokenset.created_at = moment().format("X");
tokenset.expires_at = moment().add(tokenset.expires_in - 72, "seconds").format("X");
return done(null, { ...userinfo, ...tokenset });
}));
passport.serializeUser((userData, done) => {
if (userData) {
done(null, userData);
} else {
done("error", false);
}
});
passport.deserializeUser((userData, done) => {
if (userData) {
done(null, userData);
} else {
done("error", false);
}
});
(...)
from docs.nestjs.com.
@nielsmeima Any update on this?
from docs.nestjs.com.
Guys here is what you are looking for - boilerplate with local/google auth, sessions, and ACL
https://www.gemunion.io/documentation/authorization
https://github.com/GemunIon/nestjs-auth/
@johnbiundo thanks for you code, I used it as starting point
from docs.nestjs.com.
Here is my example which works great!
// src/auth/auth.service.ts
import { Injectable } from '@nestjs/common';
import { PhotonService } from '../services/photon.service';
import { User } from '@generated/photon';
@Injectable()
export class AuthService {
constructor(private readonly photon: PhotonService) {}
async validateUser(subject: string): Promise<User> {
const user = await this.photon.users.findOne({ where: { id: subject } });
if (user) return user;
return null;
}
async createValidatedUser(subject, email, firstname, lastname): Promise<User> {
const user = await this.photon.users.create({
data: {
id: subject,
email,
firstname,
lastname,
role: 'USER',
}
});
if (user) return user;
return null;
}
}
// src/auth/onelogin.strategy.ts
import { Injectable, UnauthorizedException } from '@nestjs/common';
import { PassportStrategy } from '@nestjs/passport';
import { Strategy, Client, UserinfoResponse, TokenSet, Issuer } from 'openid-client';
import { User } from '@generated/photon';
import { AuthService } from './auth.service';
export const buildOpenIdClient = async () => {
const TrustIssuer = await Issuer.discover(`https://${process.env.AUTH_ONELOGIN_SUBDOMAIN}.onelogin.com/oidc/.well-known/openid-configuration`);
const client = new TrustIssuer.Client({
client_id: process.env.AUTH_ONELOGIN_CLIENT_ID,
client_secret: process.env.AUTH_ONELOGIN_CLIENT_SECRET,
token_endpoint_auth_method: 'client_secret_post',
});
return client;
};
@Injectable()
export class OneloginStrategy extends PassportStrategy(Strategy, 'onelogin') {
client: Client;
constructor(private readonly authService: AuthService, client: Client) {
super({
client: client,
params: {
redirect_uri: process.env.AUTH_ONELOGIN_REDIRECT_URI,
scope: process.env.AUTH_ONELOGIN_SCOPE,
},
passReqToCallback: false,
usePKCE: false,
});
this.client = client;
}
async validate(tokenset: TokenSet): Promise<User> {
const userinfo: UserinfoResponse = await this.client.userinfo(tokenset);
try {
const user = await this.authService.validateUser(userinfo.sub);
if (user) return user;
return await this.authService.createValidatedUser(
userinfo.sub, userinfo.email, userinfo.given_name, userinfo.family_name
);
} catch (err) {
throw new UnauthorizedException();
}
}
}
// src/auth/auth.module.ts
import { Module } from '@nestjs/common';
import { PassportModule } from '@nestjs/passport';
import { PhotonService } from '../services/photon.service';
import { LoginGuard } from '../guards/login.guard';
import { SessionGuard } from '../guards/session.guard';
import { AuthenticatedGuard } from '../guards/authenticated.guard';
import { GqlAuthGuard } from '../guards/gql-auth.guard';
import { AuthService } from './auth.service';
import { AuthController } from './auth.controller';
import { OneloginStrategy, buildOpenIdClient } from './onelogin.strategy';
import { SessionSerializer } from './session.serializer';
const OneloginStrategyFactory = {
provide: 'OneloginStrategy',
useFactory: async (authService: AuthService) => {
const client = await buildOpenIdClient(); // secret sauce! build the dynamic client before injecting it into the strategy for use in the constructor super call.
const strategy = new OneloginStrategy(authService, client);
return strategy;
},
inject: [AuthService]
};
@Module({
imports: [
PassportModule.register({ session: true, defaultStrategy: 'onelogin' }),
],
controllers: [AuthController],
providers: [
PhotonService,
LoginGuard,
SessionGuard,
AuthenticatedGuard,
GqlAuthGuard,
AuthService,
OneloginStrategyFactory,
SessionSerializer,
],
exports: [GqlAuthGuard, SessionGuard, LoginGuard, AuthenticatedGuard, AuthService],
})
export class AuthModule {}
// src/auth/auth.controller.ts
import { Controller, Get, UseGuards, Request } from '@nestjs/common';
import { User } from '@generated/photon';
import { CurrentUser } from '../users/user.decorator';
import { LoginGuard } from '../guards/login.guard';
import { SessionGuard } from '../guards/session.guard';
import { AuthenticatedGuard } from '../guards/authenticated.guard';
@Controller('auth')
export class AuthController {
@UseGuards(LoginGuard)
@Get('onelogin/login')
public async login() {
}
@UseGuards(LoginGuard)
@Get('onelogin/callback')
public async callback(@Request() req) {
return req.user;
}
@UseGuards(AuthenticatedGuard)
@Get('secret')
getTheSecret(@Request() req) {
return 'a secret has been returned';
}
}
// src/main.ts
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app/app.module';
import { ValidationPipe } from '@nestjs/common';
import * as session from 'express-session';
import * as passport from 'passport';
require('dotenv').config();
async function bootstrap() {
const app = await NestFactory.create(AppModule);
// Validation
app.useGlobalPipes(new ValidationPipe());
// Authentication & Session
app.use(session({
secret: process.env.AUTH_SESSION_SECRET,
resave: false,
saveUninitialized: false,
cookie: {
httpOnly: true
}
}));
app.use(passport.initialize());
app.use(passport.session());
// Cors
app.enableCors();
await app.listen(3000);
}
bootstrap();
from docs.nestjs.com.
Here's a working example of LDAP authentication in NestJS that I've created for those looking for one:
https://github.com/sbrannstrom/nestjs-passport-ldap-example
from docs.nestjs.com.
@ides15 Unfortunately, no. I ended up doing all this "openid strategy registration" in the bootstrapping section. Then I made a Module(Auth)->Controller to register the 2 routes that I need (auth and auth/cb) and a custom middleware to wrap the passport middleware.
Here is my full working code (sorry for my very bad English):
(all paths are related to "src/*" proyect)
/main.ts
file to register redis and passport configuration
import * as dotenv from "dotenv";
import * as path from "path";
import * as moment from "moment";
import * as session from "express-session";
import * as redis from "redis";
import * as redisConnect from "connect-redis";
import * as passport from "passport";
import * as bluebirdPromise from "bluebird";
dotenv.config({ path: path.resolve(process.env.PWD, "..", ".env") });
global.Promise = bluebirdPromise;
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
import { Issuer as OpenIDIssuer, Strategy as OpenIDStrategy } from "openid-client";
// OpenIDIssuer.defaultHttpOptions.timeout = 10000;
const redisStore = redisConnect(session);
const redisClient = redis.createClient({port: process.env.REDIS_PORT, host: process.env.REDIS_HOST});
function redisHandle() {
return new Promise((resolve, reject) => {
redisClient.on("error", err => {
console.error("Redis connection error");
reject(err);
});
redisClient.on("ready", (err, res) => {
if (!err) {
console.info("Redis connection successful");
resolve(res);
} else {
reject(err);
}
})
})
}
async function bootstrap() {
const app = await NestFactory.create(AppModule);
await redisHandle();
const TrustIssuer = await OpenIDIssuer.discover(process.env.SERVICE_URI_AUTH);
const params = {
redirect_uri: process.env.APP_AUTH_REDIRECT_URI,
scope: process.env.APP_AUTH_SCOPES,
}
const client = new TrustIssuer.Client({
client_id: process.env.APP_AUTH_CLIENT_ID,
client_secret: process.env.APP_AUTH_CLIENT_SECRET,
});
client.CLOCK_TOLERANCE = Infinity;
passport.use('oidc', new OpenIDStrategy({ client, params, passReqToCallback: false, usePKCE: false }, (tokenset, userinfo, done) => {
tokenset.created_at = moment().format("X");
tokenset.expires_at = moment().add(tokenset.expires_in - 72, "seconds").format("X");
return done(null, { ...userinfo, ...tokenset });
}));
passport.serializeUser((userData, done) => {
if (userData) {
done(null, userData);
} else {
done("error", false);
}
});
passport.deserializeUser((userData, done) => {
if (userData) {
done(null, userData);
} else {
done("error", false);
}
});
app.use(passport.initialize());
app.use(passport.session());
app.use(session({
name: "app.sid",
secret: 'qwerty',
resave: true,
unset: "destroy",
saveUninitialized: true,
cookie: {
secure: false,
},
store: new redisStore({
host: process.env.REDIS_HOST,
port: process.env.REDIS_PORT,
client: redisClient
})
}));
await app.listen(3000);
}
bootstrap();
/auth/auth.module.ts
to assign my 2 custom middlewares to the 2 openid routes
import { Module, NestModule, MiddlewareConsumer, RequestMethod } from '@nestjs/common';
import { AuthController } from './auth.controller';
import { PassportAuthMiddleware, PassportCallbackMiddleware } from "../common/middleware/passport";
@Module({
controllers: [
AuthController
],
providers: []
})
export class AuthModule implements NestModule {
configure(consumer: MiddlewareConsumer) {
consumer
.apply(PassportAuthMiddleware)
.forRoutes({ path: "/auth", method: RequestMethod.GET })
consumer
.apply(PassportCallbackMiddleware)
.forRoutes({ path: "/auth/cb", method: RequestMethod.GET })
}
}
/auth/auth.controller.ts
to register the 2 routes
import { Controller, Get } from '@nestjs/common';
@Controller('auth')
export class AuthController {
@Get("")
oidcLogin() { }
@Get("cb")
oidcCallback() { }
}
and finally /common/middleware/passport.ts
to wrap 2 passport middlwares
import { Injectable, NestMiddleware } from '@nestjs/common';
import { Request, Response } from 'express';
import * as passport from "passport"
@Injectable()
export class PassportAuthMiddleware implements NestMiddleware {
use(req: Request, res: Response, next: Function) {
return passport.authenticate("oidc")(req, res, next);
}
}
@Injectable()
export class PassportCallbackMiddleware implements NestMiddleware {
use(req: Request, res: Response, next: Function) {
return passport.authenticate("oidc", { successRedirect: "/", failureRedirect: "/auth" })(req, res, next);
}
}
if you guys have a better approach, let me know! :D
from docs.nestjs.com.
@sbrannstrom I think you should create a ParamService and inject that into OneloginStrategyFactory
similarly to how AuthService
is injected to the Factory. Then it will be available in the factory and you can pass it into OneloginStrategy and have it available in the super call.
I am not aware if it supports to be changed when running, but if not you should consider just creating two separate instances.
@sdoxsee please credit me somehow in the blog post, doesn't have to be a big thing, and I would really appreciate it :D
from docs.nestjs.com.
If you're struggling with NestJS, Passport and OIDC (openid-client), this article might help you (looks like its author used this thread to make it !) : https://sdoxsee.github.io/blog/2020/02/05/cats-nest-nestjs-mongo-oidc.html (related repo)
from docs.nestjs.com.
Sure I am interested! Please make sure to publish anything at all. I often read such comments and in the end I never hear or see any piece of code because the author lost interest or time to publish it.
from docs.nestjs.com.
I know, have seen a lot of the same thing. I actually have some time tonight, so I will get right to it.
from docs.nestjs.com.
Hello,
I just published a sample app that uses JWT short lived access tokens, and long lived refresh tokens.
My initial goal is to have a secure auth sample based on NestJS, that will be used by a mobile app.
The refresh token has a sliding expiration time, so if the user uses the mobile app frequently he never get disconnected.
Also, when the user is logged in, we save the client id, it can be the smartphone name or something meaningful for the user, this client id is associated to the refresh token, this gives the possibility to the user to disconnect only from one device and stay connected in the other devices, he can also disconnect from all the devices.
Here is the repo : https://github.com/abouroubi/nestjs-auth-jwt
Comments, PR's are welcome.
from docs.nestjs.com.
@MrXploder have you figured out the "client" must be an instance of "openid-client"
issue?
from docs.nestjs.com.
I made a sample repository here in case it might help some people :)
I use Nest.js, nestjs/passport with a local strategy and url redirection.
Detailed article here.
from docs.nestjs.com.
thanks @Roms1383, your solution works perfect for me. This should be in the official docs
from docs.nestjs.com.
Hey @hegelstad. I had a link to your comment in my blog references but added your name (and GitHub profile) in this commit. Please create a PR if you'd prefer something else. Thanks again for your helpful comment!
from docs.nestjs.com.
I coded up canonical Nest.js examples for Local, Google and Github (other OAuths are nearly identical ofcourse) strategies. I would be very happy to share these and possibly use them to improve the docs. How can I help?
from docs.nestjs.com.
Wow, that is a great news @nielsmeima! Feel free to create a PR if you have some spare time 🙂
from docs.nestjs.com.
@nielsmeima Hello, I just wanted to throw in my support for at least seeing your examples, even if they're ugly!
from docs.nestjs.com.
Spend the whole evening on writing the back-end part of the Medium post. Code is embedded using JSFiddles and I will also put it on Github.
I will do the front-end (Angular) part tomorrow and will probably also post it then.
from docs.nestjs.com.
Thanks for the article, going to read it tonight! Maybe @kamilmysliwiec or @BrunnerLivio wanna take a look at it. You could share it at twitter and mention https://twitter.com/nestframework?lang=en .
from docs.nestjs.com.
Yes, will share it on Twitter today. What did you think about the article?
from docs.nestjs.com.
The back-end part is live: https://medium.com/@nielsmeima/auth-in-nest-js-and-angular-463525b6e071
The article is really great and answers some unanswered questions.
Thanks a lot for it.
Would be great if it could be linked in the nestjs documentation?
from docs.nestjs.com.
I attempted to follow the Inheritance section of https://docs.nestjs.com/techniques/authentication to implement a local + session AuthGuard, but had to make some adjustments:
import { ExecutionContext, Injectable } from '@nestjs/common';
import { AuthGuard } from '@nestjs/passport';
@Injectable()
export class LocalAuthGuard extends AuthGuard('local')
{
async canActivate(context: ExecutionContext): Promise<boolean>
{
const request = context.switchToHttp().getRequest();
// End any current session
await request.logout();
// Super canActivate() must establish an authenticated user before logIn() will work
const can:boolean = await super.canActivate(context) as boolean;
if (can) {
// Establish a logIn session (https://github.com/nestjs/passport/issues/7)
await super.logIn(request);
}
return can;
}
handleRequest(err, user, info) {
return super.handleRequest(err, user, info);
}
}
It doesn't feel like that's exactly what was intended, but does work in my case.
from docs.nestjs.com.
@synapdk Thanks for sharing -- I've been trying to get Sessions working with Google OAuth2 for a long time. I have been busy with another project but am getting back into this.
Are you saying that you have a local username+password login that doesn't re-prompt because of a cookie-based session effectively working right now with just the pasted code?
I've gone through so many of these tutorials that ignore NestJS best-practices, or offer conflicting information about what to do. It seems like if you're using Sessions, according to that authentication page you linked to, you just set { session: true}
as the parameter when doing PassportModule.register(...)
, but other places say I need to turn on Passport sessions (or even Express sessions?) at the root of the app in main.ts.
I'm trying to do this with the passport-google-oauth-20 module, but no matter what, any time I hit a controller action guarded by the "googleAuthGuard" guard that I made (implementing that strategy) I get the Google prompt anyway.
I don't even see any cookies for my application in this case.
Thanks for any help!
from docs.nestjs.com.
I'm using @hegelstad 's example which is working great but I'm having one issue. My OpenID Connect provider can provide several different authentication methods, the only thing I need to do is to alter one of the params in the constructors super-call.
For example, params.acr_values: 'urn:signicat:oidc:method:sbid'
to params.acr_values: 'urn:signicat:oidc:method:siths'
in order to switch from Swedish BankID to Swedish doctors SITHS-card login.
My question is, is it possible to alter this after the application has been started?
I'm currently using dotenv to have the variables read from a file. I've tried updating the variable from an endpoint but it does not change acr_value
due to it being loaded at startup and it doesn't seem to work to update it after startup of the backend.
I'd appreciate any and all help :)
from docs.nestjs.com.
@hegelstad thank you kindly, I'll give that a try :)
from docs.nestjs.com.
@sbrannstrom I think you should create a ParamService and inject that into
OneloginStrategyFactory
similarly to howAuthService
is injected to the Factory. Then it will be available in the factory and you can pass it into OneloginStrategy and have it available in the super call.I am not aware if it supports to be changed when running, but if not you should consider just creating two separate instances.
I tried updating the acr_values with dotenv (process.env.ACR_VALUES = 'foobar'
) but it does not seem to update after the backend has been started.... It seems like a lot of extra code to create separate instances for each auth method since we will use multiple (5+ and even more in the future).... So if anyone has any more ideas, I'd greatly appreciate it :) Thanks.
from docs.nestjs.com.
Here is my example which works great!
// src/auth/auth.service.ts import { Injectable } from '@nestjs/common'; import { PhotonService } from '../services/photon.service'; import { User } from '@generated/photon'; @Injectable() export class AuthService { constructor(private readonly photon: PhotonService) {} async validateUser(subject: string): Promise<User> { const user = await this.photon.users.findOne({ where: { id: subject } }); if (user) return user; return null; } async createValidatedUser(subject, email, firstname, lastname): Promise<User> { const user = await this.photon.users.create({ data: { id: subject, email, firstname, lastname, role: 'USER', } }); if (user) return user; return null; } }// src/auth/onelogin.strategy.ts import { Injectable, UnauthorizedException } from '@nestjs/common'; import { PassportStrategy } from '@nestjs/passport'; import { Strategy, Client, UserinfoResponse, TokenSet, Issuer } from 'openid-client'; import { User } from '@generated/photon'; import { AuthService } from './auth.service'; export const buildOpenIdClient = async () => { const TrustIssuer = await Issuer.discover(`https://${process.env.AUTH_ONELOGIN_SUBDOMAIN}.onelogin.com/oidc/.well-known/openid-configuration`); const client = new TrustIssuer.Client({ client_id: process.env.AUTH_ONELOGIN_CLIENT_ID, client_secret: process.env.AUTH_ONELOGIN_CLIENT_SECRET, token_endpoint_auth_method: 'client_secret_post', }); return client; }; @Injectable() export class OneloginStrategy extends PassportStrategy(Strategy, 'onelogin') { client: Client; constructor(private readonly authService: AuthService, client: Client) { super({ client: client, params: { redirect_uri: process.env.AUTH_ONELOGIN_REDIRECT_URI, scope: process.env.AUTH_ONELOGIN_SCOPE, }, passReqToCallback: false, usePKCE: false, }); this.client = client; } async validate(tokenset: TokenSet): Promise<User> { const userinfo: UserinfoResponse = await this.client.userinfo(tokenset); try { const user = await this.authService.validateUser(userinfo.sub); if (user) return user; return await this.authService.createValidatedUser( userinfo.sub, userinfo.email, userinfo.given_name, userinfo.family_name ); } catch (err) { throw new UnauthorizedException(); } } }// src/auth/auth.module.ts import { Module } from '@nestjs/common'; import { PassportModule } from '@nestjs/passport'; import { PhotonService } from '../services/photon.service'; import { LoginGuard } from '../guards/login.guard'; import { SessionGuard } from '../guards/session.guard'; import { AuthenticatedGuard } from '../guards/authenticated.guard'; import { GqlAuthGuard } from '../guards/gql-auth.guard'; import { AuthService } from './auth.service'; import { AuthController } from './auth.controller'; import { OneloginStrategy, buildOpenIdClient } from './onelogin.strategy'; import { SessionSerializer } from './session.serializer'; const OneloginStrategyFactory = { provide: 'OneloginStrategy', useFactory: async (authService: AuthService) => { const client = await buildOpenIdClient(); // secret sauce! build the dynamic client before injecting it into the strategy for use in the constructor super call. const strategy = new OneloginStrategy(authService, client); return strategy; }, inject: [AuthService] }; @Module({ imports: [ PassportModule.register({ session: true, defaultStrategy: 'onelogin' }), ], controllers: [AuthController], providers: [ PhotonService, LoginGuard, SessionGuard, AuthenticatedGuard, GqlAuthGuard, AuthService, OneloginStrategyFactory, SessionSerializer, ], exports: [GqlAuthGuard, SessionGuard, LoginGuard, AuthenticatedGuard, AuthService], }) export class AuthModule {}// src/auth/auth.controller.ts import { Controller, Get, UseGuards, Request } from '@nestjs/common'; import { User } from '@generated/photon'; import { CurrentUser } from '../users/user.decorator'; import { LoginGuard } from '../guards/login.guard'; import { SessionGuard } from '../guards/session.guard'; import { AuthenticatedGuard } from '../guards/authenticated.guard'; @Controller('auth') export class AuthController { @UseGuards(LoginGuard) @Get('onelogin/login') public async login() { } @UseGuards(LoginGuard) @Get('onelogin/callback') public async callback(@Request() req) { return req.user; } @UseGuards(AuthenticatedGuard) @Get('secret') getTheSecret(@Request() req) { return 'a secret has been returned'; } }// src/main.ts import { NestFactory } from '@nestjs/core'; import { AppModule } from './app/app.module'; import { ValidationPipe } from '@nestjs/common'; import * as session from 'express-session'; import * as passport from 'passport'; require('dotenv').config(); async function bootstrap() { const app = await NestFactory.create(AppModule); // Validation app.useGlobalPipes(new ValidationPipe()); // Authentication & Session app.use(session({ secret: process.env.AUTH_SESSION_SECRET, resave: false, saveUninitialized: false, cookie: { httpOnly: true } })); app.use(passport.initialize()); app.use(passport.session()); // Cors app.enableCors(); await app.listen(3000); } bootstrap();
This does not work for me unfortunately, the callback endpoint returns 500 or 401 sometimes even though I was redirected to the login screen successfully but going back to my app is where the issue lies.. it bombs out on super.canActivate(context)
. Any help would be appreciated thanks.
from docs.nestjs.com.
This does not work for me unfortunately, the callback endpoint returns 500 or 401 sometimes even though I was redirected to the login screen successfully but going back to my app is where the issue lies.. it bombs out on
super.canActivate(context)
. Any help would be appreciated thanks.
Are you sure that your validate method in your OneLoginStrategy class is executing properly and returning a user object to attach to the request?
from docs.nestjs.com.
How can I use IdentityServer4 GrandType.ClientCredential? We have only clientId, clientSecret and scopes(optional), there is no user.
from docs.nestjs.com.
Related Issues (20)
- 898805435 HOT 2
- Too loud default logging level for NestJs's internal operations HOT 1
- Navigating to articles for previous versions redirects the user to the home page. HOT 1
- Suggestion for Document Function Display HOT 2
- Enhanced AI Access for NestJS Documentation HOT 1
- Update Queues docs guide to use bullmq instead of bull package HOT 2
- Difficulty in navigating topics on a page HOT 1
- Add docs on typescript-only features of `nest generate` commmand HOT 1
- WebSocketServer decorator gives unexpected value HOT 1
- Document the `type` and `disposition` options of `StreamableFile`
- Ads cover content HOT 2
- Better docs for implicit request scoped providers HOT 7
- [Docs] Small update to CLI Plugin page for clarity HOT 1
- How can I send header with kafka clientKafka=>send HOT 2
- [Docs] missing link in 'Devtools - CI/CD integration' HOT 1
- how to correctly do versioning with express adapter? HOT 2
- Unknown authentication strategy "jwt" HOT 1
- Dynamic modules exports confusion HOT 1
- [Authentication] Docs should address how to handle logging out, as well as logging in
- Issues and PR Summary HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from docs.nestjs.com.