I want to add authentication to my graphql app in nestjs. the token I receive is from auth0.
Im fairly new to nestjs I have looked at its documentation. this is the best I could comeup with and it still isnt working
this is my code where Im trying to add auth
app.module
import { Module } from '#nestjs/common';
import { ConfigModule } from '#nestjs/config';
import { MongooseModule } from '#nestjs/mongoose';
import { databaseConfig, applicationConfig } from '../../config/';
import MongoServiceClass from '../../services/Mongo';
import { ConfigModule as AppConfigModule } from '../config/config.module';
import { GraphQLModule } from '#nestjs/graphql';
import { ApolloDriver, ApolloDriverConfig } from '#nestjs/apollo';
import { LoggingPlugin } from 'src/plugins/LoggerCustom';
import { UserModule } from './user/user.module';
import { QuotaModule } from './quota/quota.module';
import { QuotaManagementModule } from './quota-management/quota-management.module';
import { BobModule } from './bob/bob.module';
import { SlModule } from './sl/sl.module';
import { SlQModule } from './sl-q/sl-q.module';
import { AuthModule } from '../auth/auth.module';
const NODE_ENV = process.env.NODE_ENV;
#Module({
imports: [
LoggingPlugin,
ConfigModule.forRoot({
load: [applicationConfig, databaseConfig],
envFilePath: `.env.${NODE_ENV}`,
isGlobal: true,
}),
MongooseModule.forRootAsync({
useClass: MongoServiceClass,
}),
AuthModule,
GraphQLModule.forRoot<ApolloDriverConfig>({
autoSchemaFile: 'schema.gql',
driver: ApolloDriver,
path: '/graphql',
playground: true,
debug: true,
}),
BobModule,
QuotaModule,
QuotaManagementModule,
AppConfigModule,
SlQModule,
SlModule,
UserModule,
],
})
export class AppModule {}
auth.module
import { Global, Module } from '#nestjs/common';
import { UserModule } from '../app/user/user.module';
import { AuthService } from './auth.service';
import { AuthResolver } from './auth.resolver';
import { GqlAuth0Guard } from './gql.guard';
import { GqlAuth0JwtStrategy } from './gql-auth0-jwt.strategy';
import { PassportModule } from '#nestjs/passport';
#Global()
#Module({
imports: [UserModule, PassportModule.register({ defaultStrategy: 'jwt' })],
providers: [AuthService, AuthResolver, GqlAuth0JwtStrategy, GqlAuth0Guard],
})
export class AuthModule {}
gql-auth0-jwt.strategy
import { Injectable, UnauthorizedException } from '#nestjs/common';
import { PassportStrategy } from '#nestjs/passport';
import { Strategy as BaseStrategy, ExtractJwt, VerifiedCallback } from 'passport-jwt';
import { passportJwtSecret } from 'jwks-rsa';
#Injectable()
export class GqlAuth0JwtStrategy extends PassportStrategy(BaseStrategy) {
domain = 'https://dev-ab454a.us.auth0.com/';
constructor() {
super({
secretOrKeyProvider: passportJwtSecret({
cache: true,
rateLimit: true,
jwksRequestsPerMinute: 5,
jwksUri: `https://dev-ab454a.us.auth0.com/.well-known/jwks.json`,
}),
jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
audience: 'https://hyyype-app.herokuapp.com/',
issuer: 'https://dev-ab454a.us.auth0.com/',
});
}
validate(payload: any, done: VerifiedCallback) {
console.log('Validate JWT-STRATEGY');
if (!payload) {
done(new UnauthorizedException(), false);
}
return done(null, payload);
}
}
gql.guard
import { ExecutionContext, Injectable } from '#nestjs/common';
import { GqlExecutionContext } from '#nestjs/graphql';
import { AuthGuard } from '#nestjs/passport';
#Injectable()
export class GqlAuth0Guard extends AuthGuard('jwt') {
getRequest(context: ExecutionContext) {
console.log('GQL-AUTH0-GUARD');
const ctx = GqlExecutionContext.create(context);
return ctx.getContext().req;
}
}
auth.resolver
import { UnauthorizedException, UseGuards } from '#nestjs/common';
import { Query, Resolver } from '#nestjs/graphql';
import { CurrentUser } from './auth.decorator';
import { GqlAuth0Guard } from './gql.guard';
#Resolver()
export class AuthResolver {
#Query(() => String)
#UseGuards(GqlAuth0Guard)
getAuthenticatedUser(#CurrentUser() user: any) {
if (!user) {
throw new UnauthorizedException('Get Auth User');
}
return user;
}
}
this is my response after i send a request I have checked the token is valid
GQL-AUTH0-GUARD
error: 586ms - Unauthorized
Related
I am integrating Stripe payment gateway through NestJS. I am getting the error which says "Nest can't resolve dependencies of the stripePaymentService". Although I am quite familiar with this error but somehow things are not working for me. I believe everything is imported where it should be.
This is complete error:
Error: Nest can't resolve dependencies of the stripePaymentService (?). Please make sure that the argument paymentIntentRepository at index [0] is available in the AppModule context.
Potential solutions:
- Is AppModule a valid NestJS module?
- If paymentIntentRepository is a provider, is it part of the current AppModule?
- If paymentIntentRepository is exported from a separate #Module, is that module imported within AppModule?
My stripePaymentModule is
/* eslint-disable prettier/prettier */
import { Module } from '#nestjs/common';
import { stripePaymentController } from './stripe-payment.controller';
import { stripePaymentService } from './stripe-payment.service';
import { TypeOrmModule } from '#nestjs/typeorm';
import { paymentIntent } from './entities/paymentIntent.entity';
import { ConfigModule } from '#nestjs/config';
#Module({
imports:[
ConfigModule.forRoot({
isGlobal: true,
}),
TypeOrmModule.forFeature([paymentIntent])],
controllers: [stripePaymentController],
providers: [stripePaymentService],
exports: [stripePaymentService],
})
export class stripePaymentModule {}
stripePaymentServices is
/* eslint-disable prettier/prettier */
import { Injectable, Logger } from '#nestjs/common';
import { InjectStripe } from 'nestjs-stripe';
import { ConfigService } from '#nestjs/config';
import Stripe from 'stripe';
import { paymentIntent } from './entities/paymentIntent.entity';
import { InjectRepository } from '#nestjs/typeorm';
import { Repository } from 'typeorm';
#Injectable()
export class stripePaymentService {
stripe: Stripe;
logger = new Logger(stripePaymentService.name);
constructor(
#InjectRepository(paymentIntent)
private readonly paymentIntent:Repository<paymentIntent>,
)
{const stripeApiKey = process.env.STRIPE_SECRET_KEY;
this.stripe = new Stripe(stripeApiKey, {
apiVersion: '2022-11-15',
});}
async payment_intent(data: any, user) {
const intent = await this.stripe.paymentIntents.create({
amount: data.amount,
currency: data.currency,
description: data.description,
payment_method_types: ['card'],
});
return await this.paymentIntent.save({'userId':user.userId, 'intent_response':JSON.stringify(intent)})
// return intent;
}
}
And finally this is app.module
/* eslint-disable prettier/prettier */
import { Module } from '#nestjs/common';
import { UsersModule } from './users/users.module';
import { ConfigModule, ConfigService } from '#nestjs/config';
import { TypeOrmModule } from '#nestjs/typeorm';
import { AuthModule } from './auth/auth.module';
import { User } from './users/entities/user.entity';
import { PassportModule } from '#nestjs/passport';
import { MailModule } from './mail/mail.module';
import { FlightBookingModule } from './flight-booking/flight-booking.module';
import { TravelBookings } from './flight-booking/entities/bookingToken.entity';
import { stripePaymentService } from './stripe/stripe-payment.service';
import { stripePaymentController } from './stripe/stripe-payment.controller';
import { StripeModule } from 'nestjs-stripe';
import { stripePaymentModule } from './stripe/stripe-payment.module';
import { paymentIntent } from './stripe/entities/paymentIntent.entity';
#Module({
imports: [
ConfigModule.forRoot({ isGlobal: true }),
StripeModule.forRoot({
apiKey: process.env.STRIPE_API_KEY,
apiVersion: '2022-11-15'
}),
TypeOrmModule.forRootAsync({
imports: [ConfigModule],
useFactory: (configService: ConfigService) => ({
type: 'postgres',
host: configService.get('DB_HOST'),
port: +configService.get<number>('DB_PORT'),
username: configService.get('DB_USERNAME'),
password: configService.get('DB_PASSWORD'),
database: configService.get('DB_NAME'),
entities: [User, TravelBookings, paymentIntent],
synchronize: true,
}),
inject: [ConfigService],
}),
PassportModule,
UsersModule,
AuthModule,
MailModule,
FlightBookingModule,
stripePaymentModule
],
controllers: [stripePaymentController],
providers: [stripePaymentService],
})
export class AppModule {}
The error is thrown from AppModule context. You wouldn't need to put stripePaymentService as a provider in AppModule.
If stripePaymentService is used by other modules, once you have export it, you just need to import the related module in a module that you want, and that would be enough.
So all you need to do is remove these lines from AppModule:
providers: [stripePaymentService]
You can remove this line as well:
controllers: [stripePaymentController]
I have the following error in nest. I've read the doc but I still don't understand what's going on. This is the full error: "[Nest] 9420 - 21/02/2022, 12:39:24 p. m. ERROR [ExceptionHandler] Nest can't resolve dependencies of the Season3Service (?). Please make sure that
the argument gModel at index [0] is available in the AppModule context". Here is my code:
app.controller.ts:
import { Controller, Get } from '#nestjs/common';
import { ClientRequest } from 'http';
import { AppService } from './app.service';
#Controller()
export class AppController {
constructor(private readonly appService: AppService) {}
#Get()
getHello(): string {
return 'Sarani Mukoe! En el Arco de la Villa del Herrero';
}
}
app.module.ts:
import { Module } from '#nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { Season3Controller } from './season3/season3.controller';
import { Season3Service } from './season3/season3.service';
import { Season3Module } from './season3/season3.module';
import { MongooseModule } from '#nestjs/mongoose';
#Module({
imports: [Season3Module, MongooseModule.forRoot('mongodb://127.0.0.1:27017/DemonSlayer')],
controllers: [AppController, Season3Controller],
providers: [AppService, Season3Service],
})
export class AppModule {}
app.service:
import { Injectable } from '#nestjs/common';
#Injectable()
export class AppService {
getHello(): string {
return 'Hello World!';
}
Then, I have the season3 module folder:
season3.controller.ts:
import { Controller, Get, Post, Put, Delete, Body, Param } from '#nestjs/common';
import { CreateSeasonDto } from './dto/create-season.dto';
import { Season } from './interfaces/Season';
import { Season3Service } from "./season3.service";
#Controller('season3')
export class Season3Controller {
constructor(private season3: Season3Service) {}
#Get()
getSeasons(): Promise<Season[]> {
return this.season3.getSeasons();
}
#Get(':p')
getSeason(#Param('p') id: string): Promise<Season>{
console.log(id);
return this.season3.getSeason(id);
}
#Post()
createSeason(#Body() season: CreateSeasonDto): string {
console.log(
`TÃtulo: ${season.titulo}. Cuerpo: ${season.cuerpo}. Realizado: ${season.realizado}`
);
return 'Insertando.... Hinokami Kagura';
}
#Put(':p1')
updateSeason(#Body() cuerpo: CreateSeasonDto, #Param('p1') id): string {
console.log(cuerpo);
console.log(id);
return `Actualizando.... Velocidad Extrema`;
}
#Delete(':id')
deleteSeason(#Param('id') id): string {
console.log(id);
return `Eliminando(${id}) .... Colmillos Afilados`;
}
}
season3.module.ts:
import { Module } from '#nestjs/common';
import { MongooseModule } from '#nestjs/mongoose';
import { Season3Controller } from './season3.controller';
import { Season3Service } from './season3.service';
import { SeasonSchema} from "./schemas/season.schema";
#Module({
imports: [MongooseModule.forFeature([
{name:'g', schema:SeasonSchema}
])],
controllers: [Season3Controller],
providers: [Season3Service],
})
export class Season3Module {}
season3.service.ts:
import { Model } from "mongoose";
import { Injectable } from '#nestjs/common';
import { InjectModel } from '#nestjs/mongoose';
import { Season } from "./interfaces/Season";
#Injectable()
export class Season3Service {
constructor(#InjectModel('g') private seasonModel: Model<Season>) {}
async getSeasons() {
return await this.seasonModel.find();
}
async getSeason(id: string) {
return await this.seasonModel.findById(id);
}
}
It looks like Season3Service is not exported so you won't be able to use it in other modules.
in season3.module.ts add export
import { Module } from '#nestjs/common';
import { MongooseModule } from '#nestjs/mongoose';
import { Season3Controller } from './season3.controller';
import { Season3Service } from './season3.service';
import { SeasonSchema} from "./schemas/season.schema";
#Module({
imports: [MongooseModule.forFeature([
{name:'g', schema:SeasonSchema}
])],
controllers: [Season3Controller],
providers: [Season3Service],
exports: [Season3Service], // <----- make Season3Service public
})
export class Season3Module {}
doc: https://docs.nestjs.com/modules#shared-modules
After this, any other module that imports Season3Module will be able to inject (user) Season3Service
in app.module.ts
import { Module } from '#nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { Season3Controller } from './season3/season3.controller';
import { Season3Module } from './season3/season3.module';
import { MongooseModule } from '#nestjs/mongoose';
#Module({
imports: [Season3Module, MongooseModule.forRoot('mongodb://127.0.0.1:27017/DemonSlayer')],
controllers: [AppController, Season3Controller],
providers: [AppService], // <---- remove Season3Service from providers
})
export class AppModule {}
Now any providers/controllers in AppModule will have access to Season3Service
So I'm trying to set up a sso system with keycloak on my angular app.
I have downloaded the keycloak library keycloak-angular#4.0.2, setted up a keycloak server at localhost:8080/auth, added the keycloak.json on the root of the app, that keycloak made for me:
{
"realm": "my-app",
"auth-server-url": "http://localhost:8080/auth",
"ssl-required": "external",
"resource": "my-app",
"public-client": true,
"confidential-port": 0
}
Also I added the keycloak initi function in the main.ts:
import { enableProdMode } from '#angular/core';
//....some other import....
import { KeycloakService } from 'keycloak-angular';
var injector = ReflectiveInjector.resolveAndCreate([KeycloakService]);
var keycloak = injector.get(KeycloakService)
if (environment.production) {
enableProdMode();
}
keycloak.init()
.then(() => platformBrowserDynamic().bootstrapModule(AppModule))
.catch(e => {
console.error(e);
});
Now, if I try to make a registration page, something like this:
export class registration implements OnInit {
constructor(keycloak:KeycloakService) {
keycloak.register();
}
ngOnInit() {
}
}
It works and sends me to a registration page and if I create an account it appears in the keycloak server.
BUT... even if I am not logged in with any account it lets me access any page, also, if I try:
keycloak.isLoggedIn().then(() => console.log("logged"), ()=>console.log("Not logged"));
The result is "logged", but if I try:
keycloak.loadUserProfile();
Then it says
The user profile was not loaded as the user is not logged in.
I can't understand how it works, am I missing something?
So my question is:
- How do I prevent pages to show if I am not logged in?
- How do I make a user log and stay logged and angular to recognize who is logged and who is not.
UPDATE: As asked I'm adding app.module.ts
import { BrowserModule, HAMMER_GESTURE_CONFIG } from '#angular/platform-browser';
import { NgModule, APP_INITIALIZER } from '#angular/core';
import { TranslateModule } from '#ngx-translate/core';
import { HttpClientModule } from '#angular/common/http';
import { KeycloakService, KeycloakAngularModule } from 'keycloak-angular';
import { initializer } from './utils/app-init';
import { AppComponent } from './app.component';
import { AppRoutingModule } from './app-routing.module';
import { AuthenticationModule } from './core/auth/authentication.module';
import { NgxPermissionsModule } from 'ngx-permissions';
import { LayoutModule } from './content/layout/layout.module';
import { PartialsModule } from './content/partials/partials.module';
import { CoreModule } from './core/core.module';
import { AclService } from './core/services/acl.service';
import { LayoutConfigService } from './core/services/layout-config.service';
import { MenuConfigService } from './core/services/menu-config.service';
import { PageConfigService } from './core/services/page-config.service';
import { UserService } from './core/services/user.service';
import { UtilsService } from './core/services/utils.service';
import { ClassInitService } from './core/services/class-init.service';
import { NgbModule } from '#ng-bootstrap/ng-bootstrap';
import { BrowserAnimationsModule } from '#angular/platform-browser/animations';
import { GestureConfig, MatProgressSpinnerModule } from '#angular/material';
import { OverlayModule } from '#angular/cdk/overlay';
import { MessengerService } from './core/services/messenger.service';
import { ClipboardService } from './core/services/clipboard.sevice';
import { PERFECT_SCROLLBAR_CONFIG, PerfectScrollbarConfigInterface } from 'ngx-perfect-scrollbar';
import { LayoutConfigStorageService } from './core/services/layout-config-storage.service';
import { LogsService } from './core/services/logs.service';
import { QuickSearchService } from './core/services/quick-search.service';
import { SubheaderService } from './core/services/layout/subheader.service';
import { HeaderService } from './core/services/layout/header.service';
import { MenuHorizontalService } from './core/services/layout/menu-horizontal.service';
import { MenuAsideService } from './core/services/layout/menu-aside.service';
import { LayoutRefService } from './core/services/layout/layout-ref.service';
import { SplashScreenService } from './core/services/splash-screen.service';
import { DataTableService } from './core/services/datatable.service';
import 'hammerjs';
import { AppAuthGuardComponent } from './utils/keycloak/app-auth-guard/app-auth-guard.component';
import { KEYCLOAK_HTTP_PROVIDER } from './utils/keycloak/keycloak.http';
const DEFAULT_PERFECT_SCROLLBAR_CONFIG: PerfectScrollbarConfigInterface = {
// suppressScrollX: true
};
#NgModule({
declarations: [AppComponent, AppAuthGuardComponent],
imports: [
BrowserAnimationsModule,
BrowserModule,
AppRoutingModule,
HttpClientModule,
LayoutModule,
PartialsModule,
CoreModule,
OverlayModule,
AuthenticationModule,
NgxPermissionsModule.forRoot(),
NgbModule.forRoot(),
TranslateModule.forRoot(),
MatProgressSpinnerModule,
KeycloakAngularModule,
],
providers: [
AclService,
LayoutConfigService,
LayoutConfigStorageService,
LayoutRefService,
MenuConfigService,
PageConfigService,
UserService,
UtilsService,
ClassInitService,
MessengerService,
ClipboardService,
LogsService,
QuickSearchService,
DataTableService,
SplashScreenService,
KeycloakService,
KEYCLOAK_HTTP_PROVIDER,
{
provide: PERFECT_SCROLLBAR_CONFIG,
useValue: DEFAULT_PERFECT_SCROLLBAR_CONFIG
},
{
provide: APP_INITIALIZER,
useFactory: initializer,
multi: true,
deps: [KeycloakService]
},
// template services
SubheaderService,
HeaderService,
MenuHorizontalService,
MenuAsideService,
{
provide: HAMMER_GESTURE_CONFIG,
useClass: GestureConfig
}
],
bootstrap: [AppComponent]
})
export class AppModule {
}
Check and add loadUserProfileAtStartUp: true, to the init config,
mine was like below, and It has resolved the issue for me,
export function initializer(keycloak: KeycloakService): () => Promise {
return (): Promise => {
return new Promise(async (resolve, reject) => {
try {
await keycloak.init({
config: {
url: environment.keycloak.issuer,
realm: environment.keycloak.realm,
clientId: environment.keycloak.clientId
},
loadUserProfileAtStartUp: true,
initOptions: {
onLoad: 'check-sso',
checkLoginIframe: true
},
bearerExcludedUrls: []
});
resolve(1);
} catch (error) {
reject(error);
}
});
};
}
Hi im new working with angular so im following a youtube tutorial to build a chat.
This project on owners github-> https://github.com/wesdoyle/base-chat
I tried to add AngularFireDatabase to providers its still not working.
I don't know why i get this error when i try to login.
That's my app.module.ts file:
import { BrowserModule } from '#angular/platform-browser';
import { NgModule } from '#angular/core';
import { FormsModule } from '#angular/forms';
import { RouterModule } from '#angular/router';
import { AppComponent } from './app.component';
import { AngularFireModule } from 'angularfire2';
import { AngularFireDatabaseModule } from 'angularfire2/database';
import { AngularFireAuthModule } from 'angularfire2/auth';
import { ChatFormComponent } from './chat-form/chat-form.component';
import { ChatroomComponent } from './chatroom/chatroom.component';
import { FeedComponent } from './feed/feed.component';
import { MessageComponent } from './message/message.component';
import { LoginFormComponent } from './login-form/login-form.component';
import { SignupFormComponent } from './signup-form/signup-form.component';
import { NavbarComponent } from './navbar/navbar.component';
import { UserListComponent } from './user-list/user-list.component';
import { UserItemComponent } from './user-item/user-item.component';
import { ChatService } from './services/chat.service';
import { AuthService } from './services/auth.service';
import { appRoutes } from '../routes';
import { environment } from '../environments/environment';
#NgModule({
declarations: [
AppComponent,
ChatFormComponent,
ChatroomComponent,
FeedComponent,
MessageComponent,
LoginFormComponent,
SignupFormComponent,
NavbarComponent,
UserListComponent,
UserItemComponent
],
imports: [
BrowserModule,
RouterModule.forRoot(appRoutes),
FormsModule,
AngularFireModule,
AngularFireDatabaseModule,
AngularFireAuthModule,
AngularFireModule.initializeApp(environment.firebase)
],
providers: [AuthService,ChatService],
bootstrap: [AppComponent]
})
export class AppModule { }
And that's the login-form.component.ts where i throw the error.
import { Component, OnInit } from '#angular/core';
import { AuthService } from '../services/auth.service';
import { AngularFireDatabase} from 'angularfire2/database';
import { Router } from '#angular/router';
#Component({
selector: 'app-login-form',
templateUrl: './login-form.component.html',
styleUrls: ['./login-form.component.css']
})
export class LoginFormComponent {
email: string;
password: string;
errorMsg: string;
constructor(private authService: AuthService, private router: Router) { }
login() {
console.log('login() called from login-form component');
this.authService.login(this.email, this.password)
.catch(error => this.errorMsg = error.message);
}
}
This is the chat.service.ts:
import { Injectable } from '#angular/core';
import { AngularFireModule } from 'angularfire2';
import { AngularFireDatabase, FirebaseListObservable, FirebaseObjectObservable } from 'angularfire2/database-deprecated';
import { AngularFireAuth } from 'angularfire2/auth';
import { Observable,of } from 'rxjs';
import { AuthService } from '../services/auth.service';
import * as firebase from 'firebase/app';
import { ChatMessage } from '../models/chat-message.model';
#Injectable()
export class ChatService {
user: firebase.User;
chatMessages: FirebaseListObservable<ChatMessage[]>;
chatMessage: ChatMessage;
userName: Observable<string>;
constructor(
private db: AngularFireDatabase,
private afAuth: AngularFireAuth
) {
this.afAuth.authState.subscribe(auth => {
if (auth !== undefined && auth !== null) {
this.user = auth;
}
this.getUser().subscribe(a => {
this.userName = a.displayName;
});
});
}
getUser() {
const userId = this.user.uid;
const path = `/users/${userId}`;
return this.db.object(path);
}
getUsers() {
const path = '/users';
return this.db.list(path);
}
sendMessage(msg: string) {
const timestamp = this.getTimeStamp();
const email = this.user.email;
this.chatMessages = this.getMessages();
this.chatMessages.push({
message: msg,
timeSent: timestamp,
userName: this.userName,
email: email });
}
getMessages(): FirebaseListObservable<ChatMessage[]> {
// query to create our message feed binding
return this.db.list('messages', {
query: {
limitToLast: 25,
orderByKey: true
}
});
}
getTimeStamp() {
const now = new Date();
const date = now.getUTCFullYear() + '/' +
(now.getUTCMonth() + 1) + '/' +
now.getUTCDate();
const time = now.getUTCHours() + ':' +
now.getUTCMinutes() + ':' +
now.getUTCSeconds();
return (date + ' ' + time);
}
}
In your chart.service.ts you have a wrong import which is depreciated,
Change
From
import { AngularFireDatabase, FirebaseListObservable, FirebaseObjectObservable } from 'angularfire2/database-deprecated';
To
import { AngularFireDatabase,FirebaseListObservable,FirebaseObjectObservable } from 'angularfire2/database';
You forgot to provide your service in the Component
#Component({
selector: 'app-login-form',
templateUrl: './login-form.component.html',
styleUrls: ['./login-form.component.css'],
providers: [AuthService]
})
hope this helps.
I have trying to implement auth provider for Node application which uses JWT
I'm getting error
TypeError: Cannot read property 'set' of undefined
My app.module.ts look like below.
import { BrowserModule } from '#angular/platform-browser';
import { ErrorHandler, NgModule } from '#angular/core';
import { IonicApp, IonicErrorHandler, IonicModule } from 'ionic-angular';
import { MyApp } from './app.component';
import { HomePage } from '../pages/home/home';
import { LoginPage } from '../pages/login/login';
import { StatusBar } from '#ionic-native/status-bar';
import { SplashScreen } from '#ionic-native/splash-screen';
import { HttpModule } from '#angular/http';
import { Auth } from '../providers/auth/auth';
import { Storage } from '#ionic/storage';
export function provideStorage() {
return new Storage( { name: '__mydb' } /* optional config */);
}
#NgModule({
declarations: [
MyApp,
HomePage,
LoginPage
],
imports: [
BrowserModule,
IonicModule.forRoot(MyApp),
HttpModule,
// IonicStorageModule.forRoot({
// name: '__mercury',
// driverOrder: ['indexeddb', 'websql']
// })
],
bootstrap: [IonicApp],
entryComponents: [
MyApp,
HomePage,
LoginPage
],
providers: [
StatusBar,
SplashScreen,
LoginPage,
{ provide: Storage, useFactory: provideStorage },
{ provide: ErrorHandler, useClass: IonicErrorHandler },
Auth
]
})
export class AppModule { }
I used documentation in https://github.com/driftyco/ionic-storage/tree/v2.0.1#configuring-storage-new-in-117
My auth.provider.ts
import { Injectable } from '#angular/core';
import { Http, Response, Headers } from '#angular/http';
import 'rxjs';
import { Storage } from '#ionic/storage';
/*
Generated class for the AuthProvider provider.
See https://angular.io/docs/ts/latest/guide/dependency-injection.html
for more info on providers and Angular 2 DI.
*/
#Injectable()
export class Auth {
baseUrl: string = "http//localhost:9080/"
constructor(public http: Http, public storage: Storage) {
console.log('Hello AuthProvider Provider');
}
createAuthorizationHeader(headers: Headers) {
let token;
this.storage.get('token').then(data => token = data);
headers.append('Athorization', token);
}
login(data) {
return this.http.post('//localhost:9080/auth', data)
.map(this.extractData);
}
isLogged() {
this.storage.get('token').then(data => {
if (data)
return true;
else
return false;
}).catch(err => {
return false;
});
return false;
}
logout() {
this.storage.remove('token');
return true;
}
private extractData(res: Response) {
console.log(res);
let body = res.json();
if (body.success === true) {
this.storage.set("token", body.token);
};
return body || {};
}
}
My platform details are
Ionic Framework: 3.2.1
Ionic Native: ^3.5.0
Ionic App Scripts: 1.3.7
Angular Core: 4.1.0
Angular Compiler CLI: 4.1.0
Node: 6.10.3
OS Platform: macOS Sierra
Navigator Platform: MacIntel
Ionic Storage : ^2.0.1
Change
login(data) {
return this.http.post('//localhost:9080/auth', data)
.map(this.extractData);
}
to
login(data) {
return this.http.post('//localhost:9080/auth', data)
.map(this.extractData.bind(this));
}
or
login(data) {
return this.http.post('//localhost:9080/auth', data)
.map((data)=>this.extractData(data));
}
Your this is not refering to your component