diff --git a/content/techniques/authentication.md b/content/techniques/authentication.md
index d225ff17e7..4cce7fc456 100644
--- a/content/techniques/authentication.md
+++ b/content/techniques/authentication.md
@@ -262,7 +262,7 @@ export class LocalStrategy extends PassportStrategy(Strategy) {
We've followed the recipe described earlier for all Passport strategies. In our use case with passport-local, there are no configuration options, so our constructor simply calls `super()`, without an options object.
-> info **Hint** We can pass an options object in the call to `super()` to customize the behavior of the passport strategy. In this example, the passport-local strategy by default expects properties called `username` and `password` in the request body. Pass an options object to specify different property names, for example: `super({{ '{' }} usernameField: 'email' {{ '}' }})`. See the [Passport documentation](http://www.passportjs.org/docs/configure/) for more information.
+> info **Hint** We can pass an options object in the call to `super()` to customize the behavior of the passport strategy. In this example, the passport-local strategy by default expects properties called `username` and `password` in the request body. Pass an options object to specify different property names, for example: `super({{ '{' }} usernameField: 'email' {{ '}' }})`. See the [Passport documentation](http://www.passportjs.org/docs/configure/) for more information.
We've also implemented the `validate()` method. For each strategy, Passport will call the verify function (implemented with the `validate()` method in `@nestjs/passport`) using an appropriate strategy-specific set of parameters. For the local-strategy, Passport expects a `validate()` method with the following signature: `validate(username: string, password:string): any`.
@@ -921,6 +921,159 @@ export class JwtStrategy extends PassportStrategy(Strategy, 'myjwt')
Then, you refer to this via a decorator like `@UseGuards(AuthGuard('myjwt'))`.
+#### Refresh-Token Functionality
+
+When the JWT strategy is in play, the token will expire within a short time frame and the user will have to re-enter authentication details to generate a new JWT. Instead, the user can be sent a refresh-token together with a JWT at the time of authentication. This refresh-token would preferably have a different secret and a longer expiration time.
+
+Since the refresh-token is generated at the same time as the JWT follwing a similar mechanism, it's convenint to keep this within the AuthModule.
+
+But, because the secret and signOptions which contains the expiration time are defined in AuthModule when registering the JwtModule, they will have to be overwritten.
+
+Update `constants.ts` in the `auth` folder to contain a new secret for refresh-token mechanism:
+
+```typescript
+@@filename(auth/constants)
+export const jwtConstants = {
+ secret: 'secretKey',
+ refreshSecret:'refreshSecretKey'
+};
+@@switch
+export const jwtConstants = {
+ secret: 'secretKey',
+ refreshSecret:'refreshSecretKey'
+};
+```
+
+Create a new JSON object called `options` and pass in the required values as follows:
+
+Then, pass this in as a second argument to `this.jwtService.sign()` function when generating the refresh-token in `auth.service.ts`.
+
+```typescript
+@@filename(auth/auth.service)
+import { Injectable } from '@nestjs/common';
+import { UsersService } from '../users/users.service';
+import { JwtService } from '@nestjs/jwt';
+import { jwtConstants } from './constants';
+
+@Injectable()
+export class AuthService {
+ constructor(
+ private usersService: UsersService,
+ private jwtService: JwtService
+ ) {}
+
+ async validateUser(username: string, pass: string): Promise {
+ const user = await this.usersService.findOne(username);
+ if (user && user.password === pass) {
+ const { password, ...result } = user;
+ return result;
+ }
+ return null;
+ }
+
+ async login(user: any) {
+ const payload = { username: user.username, sub: user.userId };
+ return {
+ access_token: this.jwtService.sign(payload),
+ refresh_token: await this.getRefreshToken(payload),
+ };
+ }
+
+ async getRefreshToken(payload: any): Promise {
+ const options = { secret: jwtConstants.refreshSecret, expiresIn: '30d' };
+ return this.jwtService.sign(payload, options);
+ }
+}
+
+@@switch
+import { Injectable, Dependencies } from '@nestjs/common';
+import { UsersService } from '../users/users.service';
+import { JwtService } from '@nestjs/jwt';
+import { jwtConstants } from './constants';
+
+@Dependencies(UsersService, JwtService)
+@Injectable()
+export class AuthService {
+ constructor(usersService, jwtService) {
+ this.usersService = usersService;
+ this.jwtService = jwtService;
+ }
+
+ async validateUser(username, pass) {
+ const user = await this.usersService.findOne(username);
+ if (user && user.password === pass) {
+ const { password, ...result } = user;
+ return result;
+ }
+ return null;
+ }
+
+ async login(user) {
+ const payload = { username: user.username, sub: user.userId };
+ return {
+ access_token: this.jwtService.sign(payload),
+ refresh_token: await this.getRefreshToken(payload),
+ };
+ }
+
+ async getRefreshToken(payload){
+ const options = { secret: jwtConstants.refreshSecret, expiresIn: '30d' };
+ return this.jwtService.sign(payload, options);
+ }
+}
+```
+
+After this, in order to regenerate the tokens, the following method will be required to be implemented in `AuthService`:
+
+```typescript
+@@filename(auth/auth.service)
+ async regenerateTokens(refresh: any): Promise {
+ const options = { secret: jwtConstants.refreshSecret };
+
+ if (await this.jwtService.verify(refresh.refreshToken, options)) {
+ // if the refreshToken is valid,
+
+ const oldSignedPayload: any = this.jwtService.decode(
+ refresh.refreshToken,
+ );
+ const newUnsignedPayload = {
+ sub: oldSignedPayload.sub,
+ username: oldSignedPayload.username,
+ };
+
+ return {
+ access_token: this.jwtService.sign(newUnsignedPayload),
+ refresh_token: await this.getRefreshToken(newUnsignedPayload),
+ };
+ }
+ }
+@@switch
+async regenerateTokens(refresh) {
+ const options = { secret: jwtConstants.refreshSecret };
+
+ if (await this.jwtService.verify(refresh.refreshToken, options)) {
+ // if the refreshToken is valid,
+
+ const oldSignedPayload = this.jwtService.decode(
+ refresh.refreshToken,
+ );
+ const newUnsignedPayload = {
+ sub: oldSignedPayload.sub,
+ username: oldSignedPayload.username,
+ };
+
+ return {
+ access_token: this.jwtService.sign(newUnsignedPayload),
+ refresh_token: await this.getRefreshToken(newUnsignedPayload),
+ };
+ }
+ }
+```
+Notice that here, the expiration time isn't included in `options` and that the oldSignedPayload is used to retrieve the usename & password (sub) for the token regeneration process.
+
+Extra steps of validation can be added to this by saving the refresh-token in a Database and checking if the refresh-token exists there when it's requested to be regenerated.
+
+
#### GraphQL
In order to use an AuthGuard with [GraphQL](https://docs.nestjs.com/graphql/quick-start), extend the built-in AuthGuard class and override the getRequest() method.