nestjs / jwt Goto Github PK
View Code? Open in Web Editor NEWJWT utilities module based on the jsonwebtoken package π
Home Page: https://nestjs.com
License: MIT License
JWT utilities module based on the jsonwebtoken package π
Home Page: https://nestjs.com
License: MIT License
[ ] Regression
[ * ] Bug report
[ ] Feature request
[ ] Documentation issue or request
[ ] Support request => Please do not submit support request here, instead post your question on Stack Overflow.
Nest version: X.Y.Z
For Tooling issues:
- Node version: XX
- Platform:
Others:
I set like this:
JwtModule.registerAsync({ useFactory() { return { secret: process.env.SECRET_OR_KEY, signOptions: { expiresIn: 300*1000 } } } })
but every time running, give me this error[Nest] 2696 - 2021/06/22 δΈε11:53:07 [ExceptionsHandler] invalid expiresIn option for string payload +5673ms Error: invalid expiresIn option for string payload at Object.module.exports [as sign] (D:\js\proposal\node_modules\jsonwebtoken\sign.js:128:22) at JwtService.sign (D:\js\proposal\node_modules\@nestjs\jwt\dist\jwt.service.js:27:20) at AdminController.login (D:\js\proposal\dist\main.js:586:41) at D:\js\proposal\node_modules\@nestjs\core\router\router-execution-context.js:38:29 at processTicksAndRejections (internal/process/task_queues.js:93:5) at async D:\js\proposal\node_modules\@nestjs\core\router\router-execution-context.js:46:28 at async D:\js\proposal\node_modules\@nestjs\core\router\router-proxy.js:9:17
if I remove like this signOptions: { expiresIn: } everything is ok so, how can I write the expiresIn ? for example, 5 minites
When signing a jwt token with a BigInt, it will not be singed correctly.
For example: 869976676795383809 will be signed as 869976676795383800
Not neccesary
No response
It should just be signed as 869976676795383800
latest
No response
No response
No response
There is a security issue in dependency jsonwebtoken
Updating to jsonwebtoken's latest version 9.0.0 resolves the vulnerability
Vulnerability details : GHSA-27h2-hvpr-p74q
No response
updating jsonwebtoken to latest version 9.0.0
9.0.0
No response
No response
No response
[ ] Regression
[ ] Bug report
[x] Feature request
[ ] Documentation issue or request
[ ] Support request => Please do not submit support request here, instead post your question on Stack Overflow.
jwtService.verify
calls jwt.verify
synchronously.
If jwt.verify
is called asynchronous, secretOrPublicKey
can be a function that can fetch the secret or public key.
I'll submit my PR shortly.
I would like to add support for json web key sets.
[ ] Regression
[X] Bug report
[ ] Feature request
[ ] Documentation issue or request
[ ] Support request => Please do not submit support request here, instead post your question on Stack Overflow.
After upgrading @nestjs deps, diff here:
"dependencies": {
- "@nestjs/common": "^6.2.0-next.2",
- "@nestjs/core": "^6.2.0-next.2",
- "@nestjs/graphql": "^6.2.2",
- "@nestjs/graphql": "^6.2.2",
- "@nestjs/jwt": "^6.1.0",
+ "@nestjs/common": "^6.4.1",
+ "@nestjs/core": "^6.4.1",
+ "@nestjs/graphql": "^6.2.4",
+ "@nestjs/jwt": "^6.1.1",
"@nestjs/passport": "^6.1.0",
- "@nestjs/platform-express": "^6.1.1",
+ "@nestjs/platform-express": "^6.4.1",
JwtService suddenly stopped being available in DI. It worked flawlessly before with this setup.
Getting error Nest can't resolve dependencies of the ContextFactory (AuthService, ?). Please make sure that the argument at index [1] is available in the ServerModule context.
Context factory:
import { Injectable } from '@nestjs/common';
import { AuthService } from 'src/auth/services/auth.service';
import { JwtService } from '@nestjs/jwt';
import { Request } from 'express';
import { IUserIdentity } from 'src/api/common/interfaces/user-identity.interface';
import { IGraphqlRequestContext } from './context.interface';
import { AuthenticationError } from 'apollo-server-core';
@Injectable()
export class ContextFactory {
constructor(
private readonly authService: AuthService,
private readonly jwtService: JwtService,
) {}
...
Server module:
import { Module } from '@nestjs/common';
import { ContextFactory } from './context.factory';
import { AuthModule } from 'src/auth/auth.module';
import { DatabaseModule } from 'src/database/database.module';
@Module({
imports: [DatabaseModule, AuthModule],
providers: [ContextFactory],
exports: [ContextFactory],
})
export class ServerModule {}
Auth Module:
import { Module } from '@nestjs/common';
import { JwtModule, JwtService } from '@nestjs/jwt';
import { AuthService } from './services/auth.service';
import { JwtStrategy } from './services/jwt.strategy';
import { PassportModule } from '@nestjs/passport';
import { UserModule } from 'src/api/modules/users/user.module';
import { Types } from 'src/common/types';
import { IConfig } from 'src/config/config.interface';
import { ConfigModule } from 'src/config/config.module';
import { DatabaseModule } from 'src/database/database.module';
import { tokenProviders } from './providers/token.providers';
import { EmailModule } from 'src/emails/email.module';
@Module({
imports: [
DatabaseModule,
PassportModule.register({ defaultStrategy: 'jwt' }),
JwtModule.registerAsync({
imports: [ConfigModule],
inject: [Types.CONFIG],
useFactory: async (config: IConfig) => {
return {
secret: config.secretKey,
signOptions: {
expiresIn: config.accessTokenExpiresIn,
},
};
},
}),
UserModule,
EmailModule,
],
providers: [AuthService, JwtStrategy, ...tokenProvider],
exports: [PassportModule, AuthService],
})
export class AuthModule {}
I would expect this to work as previously, I don't understand the cause in change of this behaviour. I didn't find any updated instructions in NestJS docs last time I checked.
Nest version: 6.4.1
Packages:
"@nestjs/common": "^6.4.1",
"@nestjs/core": "^6.4.1",
"@nestjs/graphql": "^6.2.4",
"@nestjs/jwt": "^6.1.1",
"@nestjs/passport": "^6.1.0",
"@nestjs/platform-express": "^6.4.1",
[ ] Regression
[ ] Bug report
[x] Feature request
[ ] Documentation issue or request
[ ] Support request => Please do not submit support request here, instead post your question on Stack Overflow.
When the access token expires we are forced to show the user a login form again so they can manually authenticate again, rather than automaticly renewing the token using a refresh token.
When the token expires we should get a 401, whereafter we try to refresh the access token using our refresh token, if succeeded we should get a new set of keys, else we should invalidate both tokens forcing the user to login again.
Using refresh tokens has been pretty standardized within the use of JWT's, we are making a unnatural flow without them.
https://auth0.com/blog/refresh-tokens-what-are-they-and-when-to-use-them/
"@nestjs/core": "^9.0.0",
"@nestjs/jwt": "^9.0.0",
registering module this way:
JwtModule.registerAsync({
useFactory: () => ({
secret: 'some_random_secret',
signOptions: {
expiresIn: '30m'
},
But when trying to sign with JwtService I am recieving error: "message": "secretOrPrivateKey must have a value",
What can cause this problem?
{ "message": "secretOrPrivateKey must have a value", "success": false }
No response
Expected behavior is not to ask about secretOrPrivateKey that is a deprecated option
9.0.0
9.0.0
16
No response
It assigns zero to the expiresIn property, instead of the number of seconds (JWT_EXP=60) provided in the parameter in the .env file. However, when an s is added to the parameter value (JWT_EXP=60s) it works OK.
Some more details
The strange thing happens at that line
signOptions: { expiresIn: configService.get('JWT_EXP', 60) },
It was refusing to get the JWT_EXP value from the .env file:
JWT_EXP=60
until added the βsβ as the seconds indicator, so I changed it to:
JWT_EXP=60s
After that it works OK
Surprisingly, I also noticed that when the JWT_EXP env variable is missing, e.g. I renamed it to
JWT_EXPXXX=60s
the default number value provided as second parameter in configService.get, works OK as it is expected.
Just also to mention, that as an error message I got back trying to solve the issue, the
"expiresIn" should be a number of seconds or string representing a timespan eg: "1d", "20h", 60 β¦.
https://gist.github.com/zzpzaf/7fc9bba6c294674b3fa355f44e7cc52e, https://gist.github.com/zzpzaf/27ce9f2847ce01952e510ff70d1edb3c, https://gist.github.com/zzpzaf/d558b7376e03dfb18f986c0a20bf2bb0
No response
It should read the number of seconds provided correctly, as expiration time, without s - seconds indicator
8.0.0
8.1.5
16.11.0
I also have a post at Discord
I'm trying to generate 2 tokens: authorization token and refresh token.
These tokens usually have different validity time.
I can make a PR to add the options object in jwtService.sign, jwtService.verify, in order to override the existing JWT_MODULE_OPTIONS if another options are provided when calling the methods.
This way we can generate an authorization token for 1 minute and a refresh token for let's say 8h.
[ ] Regression
[ ] Bug report
[x] Feature request
[ ] Documentation issue or request
[ ] Support request => Please do not submit support request here, instead post your question on Stack Overflow.
In the current implementation you can generate tokens with the same validity time.
Authorization token and refresh token would have the same validity time and this defies the whole purpose of this auth mechanism.
Being able to generate tokens with different validity time.
Generate tokens with different validity time.
Nest version: 5.2.1
For Tooling issues:
- Node version: 10.11.0
- Platform: Mac
Others:
[ ] Regression
[ ] Bug report
[x] Feature request
[ ] Documentation issue or request
[ ] Support request => Please do not submit support request here, instead post your question on Stack Overflow.
N/A
Hello, nestjs team there is a possibility to add an in-memory or db jwt blacklist feature?
[ ] Regression
[ ] Bug report
[x] Feature request
[ ] Documentation issue or request
[ ] Support request => Please do not submit support request here, instead post your question on Stack Overflow.
Unable to Revoked tokens.
Revoked tokensοΌ like οΌhttps://github.com/auth0/express-jwt#revoked-tokens
It is possible that some tokens will need to be revoked so they cannot be used any longer. You can provide a function as the isRevoked
option. The signature of the function is function(req, payload, done)
:
req
(Object
) - The express request
object.payload
(Object
) - An object with the JWT claims.done
(Function
) - A function with signature function(err, revoked)
to be invoked once the check to see if the token is revoked or not is complete.
err
(Any
) - The error that occurred.revoked
(Boolean
) - true
if the JWT is revoked, false
otherwise.For example, if the (iss, jti)
claim pair is used to identify a JWT:
var jwt = require('express-jwt');
var data = require('./data');
var utilities = require('./utilities');
var isRevokedCallback = function(req, payload, done){
var issuer = payload.iss;
var tokenId = payload.jti;
data.getRevokedToken(issuer, tokenId, function(err, token){
if (err) { return done(err); }
return done(null, !!token);
});
};
app.get('/protected',
jwt({secret: 'shhhhhhared-secret',
isRevoked: isRevokedCallback}),
function(req, res) {
if (!req.user.admin) return res.sendStatus(401);
res.sendStatus(200);
});
When the token is leaked, we need to undo the token.
This moring we had a failed dependency security scanning, due to an high vulrnerability risk with this package. By investigatigating, we got to the conclusion that the package jsonwebtoken
has that vulnerability, which is a dependacy of this package.
This is the link to the vulnerability: GHSA-27h2-hvpr-p74q .
There is a new version of the jsonwebtoken
which should resolve this issue. So my question is: Will @nestjs/jwt package support the newest version of jsonwebtoken
which is v9.0.0 in near future?
Thank you in advance.
The dependency jsonwebtoken
should be updated to version v9.0.0
No response
This will directly affect our production build, but passing the security scan, since we would love to continue using this package.
[ ] Regression
[x] Bug report
[ ] Feature request
[ ] Documentation issue or request
[ ] Support request => Please do not submit support request here, instead post your question on Stack Overflow.
I'm trying to set JwtModule options but those options are not getting loaded.
I'v tried both methods register()
and registerAsync()
, but none is working.
I expect that the options passed to JwtModule.register()
and JwtModule.registerAsync()
methods get loaded.
I've followed the instructions of https://docs.nestjs.com/techniques/authentication.
Then I've created an access token using RS265 algorithm. When I try to make a call to a guarded endpoint I'm getting the following error:
JsonWebTokenError: invalid algorithm
at /var/www/html/visitown-api/node_modules/jsonwebtoken/verify.js:121:19
at getSecret (/var/www/html/visitown-api/node_modules/jsonwebtoken/verify.js:90:14)
at Object.module.exports [as verify] (/var/www/html/visitown-api/node_modules/jsonwebtoken/verify.js:94:10)
at Function.module.exports [as JwtVerifier] (/var/www/html/visitown-api/node_modules/passport-jwt/lib/verify_jwt.js:4:16)
at /var/www/html/visitown-api/node_modules/passport-jwt/lib/strategy.js:104:25
at JwtStrategy._secretOrKeyProvider (/var/www/html/visitown-api/node_modules/passport-jwt/lib/strategy.js:40:13)
at JwtStrategy.authenticate (/var/www/html/visitown-api/node_modules/passport-jwt/lib/strategy.js:99:10)
at attempt (/var/www/html/visitown-api/node_modules/passport/lib/middleware/authenticate.js:366:16)
at authenticate (/var/www/html/visitown-api/node_modules/passport/lib/middleware/authenticate.js:367:7)
at /var/www/html/visitown-api/node_modules/@nestjs/passport/dist/auth.guard.js:87:3
Just for debugging reasons, I've edited node_modules/jsonwebtoken/verify.js
and placed a console.log() just before line 129, to print options
value. The result was:
{
audience: undefined,
issuer: undefined,
algorithms: [ 'HS256', 'HS384', 'HS512' ],
ignoreExpiration: false
}
Even calling JwtModule.register()
with fixed values, the options
value in verify.js
file doesn't change:
JwtModule.register({
signOptions: { mutatePayload: false, noTimestamp: false },
secret: 'superSecret',
verifyOptions: {
algorithms: [
'HS256', 'HS384',
'HS512', 'RS256',
'RS384', 'RS512',
'ES256', 'ES384',
'ES512', 'PS256',
'PS384', 'PS512',
'none'
],
complete: false,
ignoreExpiration: false,
ignoreNotBefore: false
}
}),
I need to handle JWT generated with RS256 algotithm
@nest/core: 7.3.2
@nest/jwt: 7.1.0
passport: 0.4.1
passport-jwt: 4.0.0
Node version: 12.18.2
[ ] Regression
[ ] Bug report
[ ] Feature request
[x] Documentation issue or request
[ ] Support request => Please do not submit support request here, instead post your question on Stack Overflow.
It would be interesting to add documentation/feature to be able to modify the Unauthorized exception when jwt is invalid, has expired...
Hello, i follow https://docs.nestjs.com/security/authentication to practise for jwt. i see "@nestjs/jwt": "github:nestjs/jwt" on my "package.json" but i can not import JwtService, JwtModule. It show me errors:
Module '"@nestjs/jwt"' has no exported member 'JwtModule'
and
Module '"@nestjs/jwt"' has no exported member 'JwtService'
npm: 6.14.13
node: v14.17.2
"@nestjs/cli": "^8.0.0"
what i should do?
https://docs.nestjs.com/security/authentication
npm install --save @nestjs/jwt passport-jwt
npm install --save-dev @types/passport-jwt
import { JwtModule, JwtService } from "@nestjs/jwt";
8.0.0.
8.0.0
14.17.2
No response
When using npm install --omit=dev
there are @types installed for jsonwebtoken and node.
https://github.com/mvandenbrink/nestjs-jwt-issue
@types/[email protected]
node_modules/@types/node
dev @types/node@"^16.0.0" from the root project
@types/node@"*" from @types/[email protected]
node_modules/@types/jsonwebtoken
@types/jsonwebtoken@"8.5.8" from @nestjs/[email protected]
node_modules/@nestjs/jwt
@nestjs/jwt@"^9.0.0" from the root project
Empty @types folder
9.0.0
9.1.2
16.16.0
No response
[ ] Regression
[x] Bug report
[ ] Feature request
[ ] Documentation issue or request
[ ] Support request => Please do not submit support request here, instead post your question on Stack Overflow.
When I try to use RS256
algorithm for JWT it issues tokens, but I can't access route protected by guards.
When used RS256 issue token, I should be able to access protected routes with it.
Here is a repo to reproduce https://github.com/kscerbiakas/nestjs-auth
there is .env.example
file where you can find all commands needed to reproduce the issue.
Rename it to .env
Database runs on PORT 3308 if you choose to connect via UI or CLI.
docker run --name nestjs-mysql -e MYSQL_USER=nestjs -e MYSQL_PASSWORD=nestjs -e MYSQL_DATABASE=nestjs -p 3308:3306 -d mysql/mysql-server:5.7
ssh-keygen -t rsa -b 4096 -m PEM -f jwtKey.key
openssl rsa -in jwtKey.key -pubout -outform PEM -out jwtKey.key.pub
put them next to package.json
Create user via POSTING to the route http://localhost:8080/api/v1/users
following:
{
"email": "[email protected]",
"password": "securePassword"
}
Get token via POSTING to http://localhost:8080/api/v1/auth/token
{
"email": "[email protected]",
"password": "securePassword"
}
Protected GET route http://localhost:8080/api/v1/auth/data
should return JSON
{"hello": "'hello"}
instead it returns HTTP 401
{
"statusCode": 401,
"error": "Unauthorized"
}
All routes are in auth.controller.ts
For testing purposes you can switch JWT algorithms in .env by editing DEFAULT_AUTH_ALGORITHM
variable.
Any input to solve this problem would be very helpful .
Nest version: 5.4.0
For Tooling issues:
- Node version: 10.6
- Platform: MAC
Others:
npm
WebStorm
This code doesn't work, When calling the sign methodοΌthorw an error: secretOrPrivateKey must have a value
// auth.module.ts
@Module({
imports: [
JwtModule.register({
secret: 'test',
signOptions: {
expiresIn: '60s'
}
})
],
controllers: [ AuthController ],
providers: [ LocalStrategy, ConfigService, JwtService, AuthService ]
})
// auth.service.ts
import { Injectable } from '@nestjs/common';
import { JwtService } from '@nestjs/jwt';
@Injectable()
export class AuthService {
constructor(
private readonly jwtService: JwtService
) { }
async login(user: {username: string, id: string}) {
const payload = { username: user.username, sub: user.id };
return {
access_token: this.jwtService.sign(payload)
};
}
}
but if pass parameters to sign method, It work
import { Injectable } from '@nestjs/common';
import { JwtService } from '@nestjs/jwt';
@Injectable()
export class AuthService {
constructor(
private readonly jwtService: JwtService
) { }
async login(user: {username: string, id: string}) {
const payload = { username: user.username, sub: user.id };
return {
access_token: this.jwtService.sign(payload, {
secret: 'test',
expiresIn: '60s'
})
};
}
}
Will it be caused by version differences between various dependencies?
none
No response
Normal return jwt
10.0.2
9.0.0
16.14.2
I wrote it according to the official document, so I'm a little confused
I'd like to create routes that authenticates req.user for authenticated users but still allow non authenticated users to access the route.
Would anybody be as kind to give me a workaround?
This issue lists Renovate updates and detected dependencies. Read the Dependency Dashboard docs to learn more.
These updates have all been created already. Click a checkbox below to force a retry/rebase of any.
package.json
@types/jsonwebtoken 9.0.5
jsonwebtoken 9.0.2
@commitlint/cli 19.4.0
@commitlint/config-angular 19.3.0
@nestjs/common 10.3.10
@nestjs/core 10.3.10
@nestjs/testing 10.3.10
@types/jest 29.5.12
@types/node 20.14.14
@typescript-eslint/eslint-plugin 8.0.1
@typescript-eslint/parser 8.0.1
eslint 8.57.0
eslint-config-prettier 9.1.0
eslint-plugin-import 2.29.1
husky 9.1.4
jest 29.7.0
lint-staged 15.2.8
prettier 3.3.3
reflect-metadata 0.2.2
release-it 17.6.0
rxjs 7.8.1
ts-jest 29.2.4
typescript 5.5.4
@nestjs/common ^8.0.0 || ^9.0.0 || ^10.0.0
[ ] Regression
[ X ] Bug report
[ ] Feature request
[ ] Documentation issue or request
[ ] Support request => Please do not submit support request here, instead post your question on Stack Overflow.
In error
Unknown authentication strategy "jwt"
jwt
beeing an known authentication strategy
authModule:
@Module({
providers: [
AuthenticationService,
JwtStrategy
],
imports: [
JwtModule.register({
secret: jwtConstants.secret,
signOptions: { expiresIn: "1d" },
}),
UsersModule,
],
exports: [AuthenticationService, JwtModule]
})
export class AuthenticationModule {}
User Module
@Module({
imports: [TypeOrmModule.forFeature([User])],
providers: [UsersService],
controllers: [UsersController],
exports: [UsersService]
})
export class UsersModule {}
users controller
@UseGuards(JwtAuthGuard)
@Get()
async getAll(){
return this.usersService.findAll();
}
JwtAuthGuard
@Injectable()
export class JwtAuthGuard extends AuthGuard('jwt') {}
Making use of the jwt authentication guard
Nest version: 6.11.8
For Tooling issues:
- Node version: 10.15.1
- Platform: Windows
Others:
Followed along the docs. Made sure that the Strategy is in the providers.
Doesnt work in app.controller.ts either
[ ] Regression
[ x ] Bug report
[ ] Feature request
[ ] Documentation issue or request
[ ] Support request => Please do not submit support request here, instead post your question on Stack Overflow.
Nest is unable to resolve dependencies in registerAsync
.
Dependencies are resolved.
@Module({
imports: [
DatabaseModule,
EnvironmentModule,
JwtModule.registerAsync({
useFactory: function (environment: EnvironmentService) {
return {
secretOrPrivateKey: environment.getVariable('JWT_SECRET'),
signOptions: {
expiresIn: 3600,
},
};
},
inject: [EnvironmentService],
}),
],
providers: [
AuthService,
JwtStrategy,
],
})
export class AuthModule { }
Result
Error: Nest can't resolve dependencies of the JWT_MODULE_OPTIONS (?). Please make sure that the argument at index [0] is available in the current context.
at Injector.lookupComponentInExports
I originally had useFactory
set to a lambda, but switched to a function thinking maybe that had something with the error, but that didn't help.
I also tried useClass
hoping maybe that'd resolve it, but got the same injector issues there.
Any ideas?
@nestjs/core: 5.3.4
@nestjs/jwt: 0.3.0
For Tooling issues:
- Node version: v8.12.0
- Platform: Mac
Tests are written with numerous gross mistakes. For example:
.resolves.
/ .rejects.
syntax:Lines 53 to 57 in c2c8a80
You need to put await
before expect
. See docs for Testing Asynchronous Code.
After that, the tests start to crash with a timeout. This is because the wrong configuration of jest spy. As far as I understand, jest spy is not used at all.
If you remove jest spy, the tests begin to fail due to incorrect expectations. For example sign()
returns token, but here expected secret:
Lines 79 to 81 in c2c8a80
No response
No response
Tests must be written accurately and correctly.
8.0.0
No response
No response
No response
I'm receiving the error in the title and nothing I got from searching the internet helped.
These are the relevant parts of my code:
import { Injectable } from '@nestjs/common';
import { JwtService } from '@nestjs/jwt';
import { ForbiddenException } from '@nestjs/common';
@Injectable()
export class TokenService {
constructor(private readonly jwt: JwtService) {}
async sign(payload: object) {
return this.jwt.sign({ payload });
}
async verify(token: string) {
try {
const { payload } = this.jwt.verify(token);
return payload;
} catch (exc) {
throw new ForbiddenException();
}
}
}
import { Module } from '@nestjs/common'
import { TokenService } from './token.service'
import { ConfigModule, ConfigService } from '@nestjs/config'
import { JwtModule } from '@nestjs/jwt'
@Module({
providers: [TokenService],
imports: [
JwtModule.registerAsync({
imports: [ConfigModule],
inject: [ConfigService],
useFactory: async (config: ConfigService) => ({
secret: config.get<string>('SECRET'),
}),
}),
],
exports: [TokenService],
})
export class TokenModule {}
import { Module } from '@nestjs/common'
import { AppController } from './app.controller'
import { AppService } from './app.service'
import { TokenModule } from './token/token.module'
import { AuthModule } from './auth/auth.module'
import { ProfileModule } from './profile/profile.module'
import { MongooseModule } from '@nestjs/mongoose'
import { ConfigModule, ConfigService } from '@nestjs/config'
import { JwtModule } from '@nestjs/jwt'
@Module({
imports: [
MongooseModule.forRoot('mongodb://localhost/db-name'),
ConfigModule.forRoot(),
JwtModule,
TokenModule,
AuthModule,
ProfileModule,
],
controllers: [AppController],
providers: [AppService],
})
export class AppModule {}
Unable to verify tokens when using Buffer/base64 encoded public key -> throws Invalid algorithm error.
Public key as Buffer (direct binary array) should be supported.
Use the following AuthModule:
import { Module } from '@nestjs/common';
import { JwtModule } from '@nestjs/jwt';
// import pemtools from 'pemtools';
let publicKey: string | Buffer | null = process.env.JWT_PUBLIC_KEY;
if (process.env.JWT_PUBLIC_KEY && !process.env.JWT_PUBLIC_KEY.startsWith('-----')) {
publicKey = Buffer.from(process.env.JWT_PUBLIC_KEY, 'base64');
// Workaround:
// publicKey = pemtools(publicKey, 'PUBLIC KEY').toString();
}
// console.debug('publicKey=', publicKey);
@Module({
imports: [
JwtModule.register({
publicKey,
})
],
})
export class AuthModule {}
When publicKey is a buffer, jwtService.verify(...) will always fail due to 'Invalid algorithm', however if we pass a PEM-encoded string, it will work.
One-line Base64 encoded string is much easier to put into environment variable (12-factor app principle) than PEM-encoded multiline string.
Nest version: nestjs/jwt 7.1.0
For Tooling issues:
Others:
Workaround is to use npm package pemtools
:
import pemtools from 'pemtools';
let publicKey: string | Buffer | null = process.env.JWT_PUBLIC_KEY;
if (process.env.JWT_PUBLIC_KEY && !process.env.JWT_PUBLIC_KEY.startsWith('-----')) {
publicKey = Buffer.from(process.env.JWT_PUBLIC_KEY, 'base64');
// Workaround:
publicKey = pemtools(publicKey, 'PUBLIC KEY').toString();
}
However this is unnecessary as what it does is re-encoding Buffer which is already binary into PEM-encoded string which will be decoded into binary string again.
Related to #94.
[ ] Regression
[ ] Bug report
[ ] Feature request
[x] Documentation issue or request
[ ] Support request => Please do not submit support request here, instead post your question on Stack Overflow.
Documentation on how to use this lib, is made for people who know NestJS very much. I simply don't know how to use it.
I am working on my project, and I am thinking about security
More detailed examples geared toward NestJS beginners. Or at least an example folder inside the repo would also do the trick.
[ ] Regression
[ ] Bug report
[x] Feature request
[ ] Documentation issue or request
[ ] Support request => Please do not submit support request here, instead post your question on Stack Overflow.
Currently, there is no way that when we sign
or verify
a token, we can override the options
provided in JwtModule.register()
or JwtModule.registerAsync()
.
There should be a way to override the options.
When we need to use the same JwtService
to create/verify different tokens with different secrets (refreshToken
vs accessToken
)
Nest version: X.Y.Z
For Tooling issues:
- Node version: XX
- Platform:
Others:
[ ] Regression
[x] Bug report
[ ] Feature request
[ ] Documentation issue or request
[ ] Support request => Please do not submit support request here, instead post your question on Stack Overflow.
I am following the documentation present here
https://docs.nestjs.com/techniques/authentication#jwt-functionality
To have faster support I have created a git repository with the problem
https://github.com/Sano123456/nestjs-jwt
in AuthModule if I do as described in documentation and just import UserModule, it return me error of circular dependency between UserModule and AuthModule
@Module({
imports:[
UsersModule,
PassportModule
],
providers: [AuthService],
controllers: [AuthController],
exports:[AuthService, LocalStrategy]
})
export class AuthModule {}
[ExceptionHandler] Nest cannot create the AuthModule instance.
The module at index [0] of the AuthModule "imports" array is undefined.
Potential causes:
- A circular dependency between modules. Use forwardRef() to avoid it. Read more: https://docs.nestjs.com/fundamentals/circular-dependency
- The module at index [0] is of type "undefined". Check your import statements and the type of the module.
Scope [AppModule -> UsersModule] +6ms
Possibile solution in imports array of AuthModule instead of UserModule put forwardRef(() => UsersModule),
this actually remove the error but not sure if this is the right way
it says that can't find LocalStrategy class even if it's present and declared in AuthModule
[ExceptionHandler] Nest cannot export a provider/module that is not a part of the currently processed module (AuthModule). Please verify whether the exported LocalStrategy is available in this particular context.
Possible Solutions:
- Is LocalStrategy part of the relevant providers/imports within AuthModule?
Possibile solution right now I don't have any solution, I just remove it to understand what is the problem
after removing LocalStrategy,
[ExceptionHandler] Nest can't resolve dependencies of the AuthService (?). Please make sure that the argument dependency at index [0] is available in the AuthModule context.
Potential solutions:
- If dependency is a provider, is it part of the current AuthModule?
- If dependency is exported from a separate @Module, is that module imported within AuthModule?
@Module({
imports: [ /* the Module containing dependency */ ]
})
+1ms
Error: Nest can't resolve dependencies of the AuthService (?). Please make sure that the argument dependency at index [0] is available in the AuthModule context.
to be configured as described
https://github.com/Sano123456/nestjs-jwt
nest -v -> 7.4.1
For Tooling issues:
- Node version: v10.15.2
- npm version: 6.14.6
- Platform: any
Others:
[x] Regression
[x] Bug report
[ ] Feature request
[ ] Documentation issue or request
[ ] Support request => Please do not submit support request here, instead post your question on Stack Overflow.
Totally broken, neither register
or registerAsync
works.
Can't seem to resolve JWT_MODULE_OPTIONS
nor the dependencies in registerAsync
if that is used.
Error: Nest can't resolve dependencies of the JwtService (?). Please make sure that the argument at index [0] is available in the JwtModule context.
Resolve JWT_MODULE_OPTIONS
.
JwtModule.register({
secretOrPrivateKey: process.env.APP_SECRET,
}),
Nest version: 5.4.0
For Tooling issues:
- Node version: 10.9.0
- Platform: WSL
[ ] Regression
[ ] Bug report
[x] Feature request
[ ] Documentation issue or request
[ ] Support request => Please do not submit support request here, instead post your question on Stack Overflow.
secretOrKeyProvider
must return the key synchronously
If we are using jwks, we need to get this key from a http endpoint. Therefore, secretOrKeyProvider must support promises
Auth0 exposes the public keys via JWKS (https://github.com/auth0/node-jwks-rsa/tree/master/examples/express-demo)
Nest version: 7.0.0
For Tooling issues:
- Node version: 12
- Platform: Mac
failed to generate token and throw exception secretOrPrivateKey has a minimum key size of 2048 bits for RS256. this issue only happen when running inside docker alpine (FROM node:18.14-alpine3.17) normal run on my local
Sorry repo in my company git
upgrade package.json like below :
"@nestjs/jwt": "10.0.2"
"passport-jwt": "^4.0.1",
"@types/passport-jwt": "^3.0.8",
normal like "@nestjs/jwt": "9.0.0",
10.0.2
9.3.9
18.14
No response
[ ] Regression
[ ] Bug report
[x] Feature request
[x] Documentation issue or request
[ ] Support request
Currently there is no way to sign the token dynamically. (see user.secret
comment). So far based on the documentation I can't seem to find a good solution. Maybe more docs are missing? In case somebody asks the same question I have created a SO post:
@Injectable()
export class AuthService {
public constructor(private readonly jwtService: JwtService, private readonly userService: UserService) {}
public async createToken(email: string): Promise<JwtReply> {
const expiresIn = 60 * 60 * 24;
const user = await this.userService.user({ where: { email } });
const accessToken = await this.jwtService.signAsync({ email: user.email }, /* user.secret ,*/ { expiresIn });
return {
accessToken,
expiresIn,
};
}
}
Sign should work similar to jwt-token libraries sign method. Re-add second parameter as secret key rather than options.
Add a secretOrPrivateKeyProvider similar to PassportStrategy
of @nestjs/passport
JwtModule.register({
secretOrPrivateKeyProvider: userService.provideSecret,
signOptions: {
expiresIn: 3600,
},
})
See first code example above
I'm new to nestjs and cautious about security. This might be opinionated and I apologise if this is the case here. For security purposes rather than relying on a single secret, if stolen, the whole infrastructure is compromised. When stealing a single secret a single user is compromised and the damage lowered when using dynamic secret signing. "stealing" may sound vague, but I hope it simplifies what I mean in general.
Am trying JWT in my code and i got an error of -
:Error: Nest can't resolve dependencies of the UsersService (?). Please make sure that the argument studentsModel at index [0] is available in the AppModule context
Potential solutions:
But i didn't understand how to solve this.
[ ] Regression
[x] Bug report
[ ] Feature request
[ ] Documentation issue or request
[ ] Support request => Please do not submit support request here, instead post your question on Stack Overflow.
When using the decode method, the 2nd argument 'options' is not optional as it is in the jsonwebtoken package.
No response
9.0.0 -> 10.0.1
Although the library jsonwebtoken
is upgraded to version 9, the type declaration library @types/jsonwebtoken
is still on 8.5.9.
@Module({
imports: [
JwtModule.registerAsync({
useFactory () {
return {
secret: SECRET,
// allowInsecureSizes is not in the `@types/jsonwebtoken` type declaration file.
signOptions: { algorithm: 'HS256', allowInsecureKeySizes: true },
};
},
}),
]
})
allowInsecureKeySizes
should be autocompleted in jwt.SignOptions
type.
No response
[ ] Regression
[ ] Bug report
[ ] Feature request
[x] Documentation issue or request
[ ] Support request => Please do not submit support request here, instead post your question on Stack Overflow.
I am trying to decode a signed token without verifying the JWT. Is this possible?
[ ] Regression
[x] Bug report
[ ] Feature request
[ ] Documentation issue or request
[ ] Support request => Please do not submit support request here, instead post your question on Stack Overflow.
Type checker not working on JwtModule.registerAsync
when using useFactory
funcition.
It's wired because I check the type and It is correct.
Also there is any issue on that file.
Nest version: X.Y.Z
For Tooling issues:
- Node version: XX
- Platform:
Others:
Also I know this is not the place for this but...
Nest such is a really great project. I love it β€ I would like to contribute on anything if posible.
Time ago I wanted to create some framework in typescript in witch you could return promises and throw exceptions instead of using the res
object. But then I check this project and It's just like my dream come true.
So if thereΒ΄s anything I can do please tell me. From pull requests to docs contribution π
It looks like tokens cannot be verified if the secret is Base64 encoded. The issue is caused by the implementation of the verify method. Link to Method
verify<T extends object = any>(
token: string,
options?: jwt.VerifyOptions
): T {
const verifyOptions = this.mergeJwtOptions(options, 'verifyOptions');
const secret = this.getSecretKey(
token,
options,
'publicKey',
JwtSecretRequestType.VERIFY
);
return jwt.verify(token, secret.toString(), verifyOptions) as T;
}
The issue is being caused by the stringification of the secret in this line:
return jwt.verify(token, secret.toString(), verifyOptions) as T;
Check out the typescript definitions for the jsonwebtoken library, the underlying library for nestjs/jwt:
export type Secret =
| string
| Buffer
| { key: string | Buffer; passphrase: string };
And here is the Typescript definition for the verify implementation:
export function verify(
token: string,
secretOrPublicKey: string | Buffer,
options?: VerifyOptions,
): object | string;
And here are the type definitions for the nestjs/jwt:
export interface JwtModuleOptions {
signOptions?: jwt.SignOptions;
secret?: string | Buffer; // <------- THIS ONE HERE
publicKey?: string | Buffer;
privateKey?: jwt.Secret; // <----- ALSO, THIS ONE HERE
/**
* @deprecated
*/
secretOrPrivateKey?: jwt.Secret;
secretOrKeyProvider?: (
requestType: JwtSecretRequestType,
tokenOrPayload: string | object | Buffer,
options?: jwt.VerifyOptions | jwt.SignOptions
) => jwt.Secret;
verifyOptions?: jwt.VerifyOptions;
}
The verify method CAN take a buffer but it is being stringified here. This causes keys that are Base64 encoded to fail always when used with the nestjs/jwt package.
JWT should be verified correctly if the the secret is of Buffer type. The buffer should not be using toString() in the verify method.
Gist of code to verify problematic code
We would love to stick to the nest ecosystem, but our company uses base64 buffers for creating JWT's.
Nest version: 6.7.2
For Tooling issues:
- Node version: 10.15.1
- Platform: Mac
Others:
JwtModule.register({ secret: "configuration.auth.secretKey", signOptions: { expiresIn: '1s' }, })
This token never expires
Then I tried the secret change, and token is still valid
[ ] Regression
[x] Bug report
[ ] Feature request
[ ] Documentation issue or request
[ ] Support request => Please do not submit support request here, instead post your question on Stack Overflow.
when jwt expired,I get a error like this
[Nest] 16572 - 2020-02-14 13:41:37 [ExceptionsHandler] Object:
{
"statusCode": 401,
"error": "Unauthorized"
}
+5577099ms
Error: [object Object]
at MixinAuthGuard.handleRequest (D:\Code\nest-test\node_modules\_@nestjs_passport@6.1.1@@nestjs\passport\dist\auth.guard.js:63:30)
at D:\Code\nest-test\node_modules\_@nestjs_passport@6.1.1@@nestjs\passport\dist\auth.guard.js:47:120
at D:\Code\nest-test\node_modules\_@nestjs_passport@6.1.1@@nestjs\passport\dist\auth.guard.js:78:24
...
and response is
{"statusCode":500,"message":"Internal server error"}
so, how can I use filter catch this error
use filter catch this exception 401
Nest version: 6.8.2
@nest/password version: 6.1.1
@nest/jwt version: 6.1.1
For Tooling issues:
- Node version: XX
- Platform: Windows
Others:
[ ] Regression
[x] Bug report
[ ] Feature request
[ ] Documentation issue or request
[ ] Support request => Please do not submit support request here, instead post your question on Stack Overflow.
import { JwtService } from '@nestjs/jwt';
This produces error:
Module '"@nestjs/jwt"' has no exported member 'JwtService'.
There should be no error.
Install version 8.0.0 using npm i -S @nestjs/jwt
and try importing anything from the package.
Package unusable.
Nest version: 8.0.2
For Tooling issues:
- Node version: v15.6.0
- Platform: Windows
Others:
I noticed that in `node_modules\@nestjs\jwt`, there is no `dist\` directory.
[ ] Regression
[x] Bug report
[ ] Feature request
[ ] Documentation issue or request
[ ] Support request => Please do not submit support request here, instead post your question on Stack Overflow.
When compiling the nestjs project, I'm getting the
[ExceptionHandler] Nest can't resolve dependencies of the AuthService (UsersService, ?). Please make sure that the argument at index [1] is available in the AppModule context. +2ms
Error: Nest can't resolve dependencies of the AuthService (UsersService, ?). Please make sure that the argument at index [1] is available in the AppModule context.
error.
It should be working.
My auth.module.ts:
import { Module } from '@nestjs/common';
import { AuthService } from './auth.service';
import { UsersModule } from '../users/users.module';
import { JwtModule } from '@nestjs/jwt';
import { PassportModule } from '@nestjs/passport';
import { JwtStrategy } from './jwt.strategy';
@Module({
imports: [
UsersModule,
PassportModule.register({ defaultStrategy: 'jwt' }),
JwtModule.register({
secret: 'secretKey',
signOptions: {
expiresIn: 86400,
},
}),
],
providers: [AuthService, JwtStrategy],
exports: [AuthService],
})
export class AuthModule {}
My user.module.ts:
import { Module } from '@nestjs/common';
import { UsersService } from './users.service';
import { UsersController } from './users.controller';
import { TypeOrmModule } from '@nestjs/typeorm';
import { UserRepository } from './user.repository';
@Module({
imports: [TypeOrmModule.forFeature([UserRepository])],
providers: [UsersService],
controllers: [UsersController],
exports: [UsersService],
})
export class UsersModule {}
My auth.service.ts:
@Injectable()
export class AuthService {
constructor(private readonly usersService: UsersService, private readonly jwtService: JwtService) {}
async validateUser(userId: string, pass: string): Promise<any> {
const user = await this.usersService.findUserById(userId);
if (user && user.password === pass) {
const { password, ...result } = user;
return result;
}
return null;
}
async login(user: User) {
const payload: JwtPayload = { id: user.user_id };
return {
access_token: this.jwtService.sign(payload),
};
}
}
My app.module.ts:
import { Module } from '@nestjs/common';
import { typeOrmConfig } from './config/typeorm.config';
import { TypeOrmModule } from '@nestjs/typeorm';
import { ProductsModule } from './products/products.module';
import { UsersModule } from './users/users.module';
import { AuthService } from './auth/auth.service';
import { AuthModule } from './auth/auth.module';
@Module({
imports: [TypeOrmModule.forRoot(typeOrmConfig), ProductsModule, UsersModule, AuthModule],
providers: [AuthService],
})
export class AppModule {}
I've done everything what the tutorial is saying, I couldn't find a place in a code with an obvious error.
From my understanding the error is talking about this exact place in the code:
export class AuthService {
constructor(private readonly usersService: UsersService, private readonly jwtService: JwtService) {}
and so apparently it can't find JwtService, but clearly, I'm loading it in auth.module.ts, as JwtModule. Not sure what else could be wrong here.
Also what is worth mentioning, everything worked correctly up untill I've added jwtService in the AuthService constructor.
Nest version: 6.4.1
For Tooling issues:
- Node version: Yarn 1.16.0
- OS: Mac
After using registerAsync or register at module level with secret, that seem to be undefined at sign methode.
you can check gist of the module here : https://gist.github.com/omarberrami/d6bf3eefee8e967b836a44b10e2679ff
you can check the service gist here : https://gist.github.com/omarberrami/f91140240bac674e03fdde364a217875
https://gist.github.com/omarberrami/d6bf3eefee8e967b836a44b10e2679ff , https://gist.github.com/omarberrami/f91140240bac674e03fdde364a217875
follow nest documentation to implement jwt, and sign function wil trigger an error
the secred passed to module need to be availeble at signe methode without ovverding it againat signe methode level
9.0.0
9.0.1
12.22.10
secretOrPrivateKey must have a value at Object.module.exports [as sign] (/Users/cloudeco/Documents/bee-in/api-app-itiforums/node_modules/jsonwebtoken/sign.js:107:20) at JwtService.sign (/Users/cloudeco/Documents/bee-in/api-app-itiforums/node_modules/@nestjs/jwt/dist/jwt.service.js:29:20) at AuthService.loginWithCredentials (/Users/cloudeco/Documents/bee-in/api-app-itiforums/src/auth/auth.service.ts:45:44) at processTicksAndRejections (internal/process/task_queues.js:97:5) at AuthController.authByEmailAndPass (/Users/cloudeco/Documents/bee-in/api-app-itiforums/src/auth/auth.controller.ts:11:12) at /Users/cloudeco/Documents/bee-in/api-app-itiforums/node_modules/@nestjs/core/router/router-execution-context.js:46:28 at /Users/cloudeco/Documents/bee-in/api-app-itiforums/node_modules/@nestjs/core/router/router-proxy.js:9:17
Currently I have to call JwtModule
every where, how could I register it once and I could use JwtService
every where?
@Module({
providers: [],
exports: [JwtModule],
imports: [
JwtModule.register({
secret: process.env.SECRET
})
],
})
[ ] Regression
[X] Bug report
[ ] Feature request
[ ] Documentation issue or request
[ ] Support request => Please do not submit support request here, instead post your question on Stack Overflow.
Using deprecated secretOrPrivateKey option in register method.
JwtModule.register({
secretOrPrivateKey: 'ssshhhh',
signOptions: { expiresIn: '60s' },
})
causes error message: [JwtService] "secretOrPrivateKey" has been deprecated, please use the new explicit "secretOrKeyProvider" or use "privateKey"/"publicKey" exclusively.
The error message omits the third option: explicit "secret" option. For example, this is valid:
JwtModule.register({
secret: 'ssshhhh',
signOptions: { expiresIn: '60s' },
})
Error message should read:
[JwtService] "secretOrPrivateKey" has been deprecated, please use the new explicit "secretOrKeyProvider" or use "secret" or "privateKey"/"publicKey" exclusively.
Nest version: X.Y.Z
For Tooling issues:
- Node version: XX
- Platform:
Others:
There is an error with this repository's Renovate configuration that needs to be fixed. As a precaution, Renovate will stop PRs until it is resolved.
Error type: undefined. Note: this is a nested preset so please contact the preset author if you are unable to fix it yourself.
Hi Team,
My code was running properly and all of a sudden I'm getting this error.
[Nest] 10348 - 16/02/2020, 11:14:40 pm [ExceptionHandler] metatype is not a constructor +17ms TypeError: metatype is not a constructor at Injector.instantiateClass (C:\Users\susha\Documents\Nest.js\Task Management\node_modules\@nestjs\core\injector\injector.js:288:19) at callback (C:\Users\susha\Documents\Nest.js\Task Management\node_modules\@nestjs\core\injector\injector.js:75:41) at processTicksAndRejections (internal/process/task_queues.js:97:5) at async Injector.resolveConstructorParams (C:\Users\susha\Documents\Nest.js\Task Management\node_modules\@nestjs\core\injector\injector.js:116:24) at async Injector.loadInstance (C:\Users\susha\Documents\Nest.js\Task Management\node_modules\@nestjs\core\injector\injector.js:79:9) at async Injector.loadInjectable (C:\Users\susha\Documents\Nest.js\Task Management\node_modules\@nestjs\core\injector\injector.js:32:9) at async Promise.all (index 0) at async InstanceLoader.createInstancesOfInjectables (C:\Users\susha\Documents\Nest.js\Task Management\node_modules\@nestjs\core\injector\instance-loader.js:57:9) at async C:\Users\susha\Documents\Nest.js\Task Management\node_modules\@nestjs\core\injector\instance-loader.js:28:13 at async Promise.all (index 6)
I've tried installing and uninstalling the node_modules it still didn't help.
I can't find the problem too using the error stack.
Could anyone please check where is it breaking?
This is the link to my repository in which I'm facing the issue.
Thanks!
[ ] Regression
[x] Bug report
[ ] Feature request
[ ] Documentation issue or request
[ ] Support request => Please do not submit support request here, instead post your question on Stack Overflow.
Nest can't resolve dependencies in JWT_MODULE_OPTIONS
Dependencies are resolved.
import { JwtModule } from '@nestjs/jwt';
@Module({
imports: [
TypeOrmModule.forFeature([User, Role]),
ConfigModule,
PassportModule.register({ defaultStrategy: 'jwt' }),
JwtModule.registerAsync({
inject: [ConfigService],
useFactory: async (configService: ConfigService) => ({
secretOrPrivateKey: config.jwtSecret,
type: configService.dbType as any,
host: configService.dbHost,
port: configService.dbPort,
username: configService.dbUsername,
password: configService.dbPassword,
database: configService.dbName,
entities: ['./src/data/entities/*.ts'],
signOptions: {
expiresIn: config.expiresIn,
},
}),
}),
],
providers: [AuthService, JwtStrategy],
controllers: [AuthController],
})
export class AuthModule { }
Nest can't resolve dependencies of the JWT_MODULE_OPTIONS (?). Please make sure that the argument at index [0] is available in the JwtModule context. +52ms
Nest version: 6.3.0
JWT version: 6.0.0 (6.1.1 same problem)
For Tooling issues:
- Node version: 10.12.0
- Platform: Windows 10
Others:
How to invalidate a token based on this example?
https://github.com/nestjs/nest/tree/master/sample/19-auth-jwt
I reissue the token when requesting logout API, the expiration time of the original token remains unchanged, and I can still use the old token to request data. What should I do?
https://github.com/wjw-gavin/nest-study
No response
none
10
9
18
No response
JwtModule does not use the nestjs v9 ModuleOptionsBuilder. That said we cannot use the providers from the parent module when we want to pass the options from a parent module (as describe here: nestjs/nest#9935).
Try to use this kind of configuration described in the merged pull request.
JwtModule.registerAsync({
useFactory(opt: AuthenticationOptions) {
return opt.jwtOptions;
},
inject: [AuthenticationOptions],
}),
When using this code we cannot inject JwtService
in our service from our parent module
Allow provideInjectionTokensFrom
to be able to use the config providers from a parent module
9.0.0
9.0.11
16.15.1
No response
A declarative, efficient, and flexible JavaScript library for building user interfaces.
π Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. πππ
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google β€οΈ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.