Unknown authentication strategy jwt in hapijs jwt authentication - jwt

I am using hapi-auth-jwt for authentication purpose
But on the login when i use auth strategy as jwt, it shows Unknown authentication strategy jwt in /login
I am using glue
Here is my code
manifest.js:
module.exports = {
server : {},
connections : [
{
host: apiConfig.server.host,
port: apiConfig.server.port
},
],
registrations : [
{
'plugin': {
register: 'hapi-auth-jwt',
},
},
]
};
server.js:
glue.compose(manifest, manifestOptions, (error, server) => {
if(error)
throw error;
mongoose.connect("mongodb://" + apiConfig.database.host + '/' + apiConfig.database.dbname, (error) => {
if(error)
console.log(error);
else
console.log('mongodb connected');
});
server.app.assetsPath = Path.resolve(__dirname, '../assets');
server.start(() => {
console.log("Api server running " + server.info.uri);
});
server.auth.strategy('jwt', 'jwt', {
key: apiConfig.authentication.secretKey,
verifyOptions: {
algorithms: ['HS256']
}
});
}
route.js:
{
method : 'POST',
path : '/login',
config : {
auth: {
strategy: 'jwt',
},
tags : ['api'],
description: 'Customer login',
plugins : {
'hapi-swagger': {
payloadType: 'form'
}
},
/*validate : {
failAction: Relish.failAction,
options : {
abortEarly: false
},
payload : loginSchema
},*/
},
handler: handler.loginHandler
}

I was loading my route in the glue manifest, after that only I am registering my auth. So I included the auth registration in glue's manifest before the route registration

Related

NextAuth + TwitterProvider + FirestoreAdapter => Missing Screen Name

I'm using next-auth along with next-auth/firebase-adapter packages to log to my web app via Twitter. The flow is working nicely, but I can not obtain the user's screenname (aka handle).
Before using next-auth I've been using Firebase auth(). In their package, the user's screen name has always been available.
I've been playing around with NextAuthOptions but to no avail.
Does anyone know how to make add the user's screenname to the session?
export const authOptions: NextAuthOptions = {
session: {
strategy: 'jwt',
},
adapter: FirestoreAdapter(firebaseConfig),
pages: {
signIn: '/sign-in',
},
callbacks: {
session: ({ session, token }) => {
return {
...session,
user: {
...session.user,
id: token.sub!,
},
}
},
},
events: {
createUser: async ({ user }) => {
const ref = admin
.firestore()
.collection(Constants.UsersTable)
.doc(user.id)
await ref.set(
{
screenName: <MISSING>,
daily_target: 0,
onboarded: false,
},
{ merge: true }
)
},
},
providers: [
TwitterProvider({
clientId: process.env.TWITTER_AUTH_CLIENTID,
clientSecret: process.env.TWITTER_AUTH_CLIENTSECRET,
version: '2.0',
}),
],
}
Instead of obtaining the screenname I decided to obtain the providerAccountToken and add it to my JWT token with a next-auth callback.
This is even better as I use the unique user id instead of a public handle (which the user might change in the future).
callbacks: {
jwt: ({ token, account = {} }) => {
// Persist the OAuth access_token to the token right after signin
if (account.providerAccountId) {
token.providerAccountId = account.providerAccountId
}
return token
},
},

useSession stays in loading state after sign-in using REST API

I am using the Credentials provider and next-auth 4.3.1
I go to page /protected
This page does useSession({ required: true, onUnauthenticated: () => router.push('/login?redirect=/protected') })
I login on the login page I got redirected too with this code:
const { data: { csrfToken } } = await axios.get('/api/auth/csrf');
const res = await axios
.post(
'/api/auth/callback/credentials',
{
json: true,
csrfToken,
redirect: false,
email: form.email,
password: form.password
},
{
headers: { 'Content-Type': 'application/x-www-form-urlencoded' }
}
);
router.push(router.query.redirect || '/');
After succesfully logging in, notice it pushes back router.push(router.query.redirect), so it takes me back to /protected
However useSession returns { data: undefined, status: loading } and triggers onUnauthenticated, taking me back to the login page
Now, I don't login again, I just type in URL bar https://localhost:3000/protected it will load the protected page and useSession properly finds the logged-in session.
Is there something I have to do to make useSession see signIn was just called?
Here is my [...nextauth].ts:
const handler = NextAuth({
secret: process.env.NEXTAUTH_SECRET,
session: {
strategy: 'jwt'
},
debug: process.env.NODE_ENV === 'development',
providers: [
CredentialsProvider({
credentials: {
email: { label: 'Email', type: 'text' },
password: { label: 'Password', type: 'password' }
},
async authorize(credentials, req) {
////// removed
}
})
],
pages: {
signIn: '/login'
},
callbacks: {
async jwt({ token, user }) {
if (user) {
token.user = { id: user.id };
}
return token;
},
async session({ session, token }) {
if (session?.user) {
session.user.id = token.user.id;
}
return session;
}
}
});

Cannot get a response from PostgreSQL server

I freely admit that I am completely new to next-auth and the documentation for Credentials is understandably very light. I have got the email link process to work perfectly and will be moving users across top this.
Unfortunately, I have a lot of user data that will require credentials to login and, after spending a few days getting nowhere, I just want to get some idea of what I am doing wrong! This is my [...nextauth].js file:
import NextAuth from "next-auth";
import Providers from "next-auth/providers";
import axios from 'axios'
const options = {
providers: [
Providers.Email({
server: {
host: process.env.EMAIL_SERVER_HOST,
port: process.env.EMAIL_SERVER_PORT,
auth: {
user: process.env.EMAIL_SERVER_USER,
pass: process.env.EMAIL_SERVER_PASSWORD
}
},
from: process.env.EMAIL_FROM
}),
Providers.Credentials({
credentials: {
mem_num: { label: "Membership Number", type: "text", placeholder: "12345" },
password: { label: "Password", type: "text" }
},
authorize: async (credentials) => {
console.log("credentials: ", credentials)
try {
const data = {
mem_num: credentials.mem_num,
password: credentials.password
}
const user = await login(data)
if (user) {
console.log('user:', user)
return user
}
} catch (error) {
if (error.response) {
console.log(error.response)
Promise.reject(new Error('Invalid Number and Password combination'))
}
}
}
})
],
site: process.env.NEXTAUTH_URL || "http://localhost:3000",
database: process.env.DATABASE_URL,
session: {
// Use JSON Web Tokens for session instead of database sessions.
// This option can be used with or without a database for users/accounts.
// Note: `jwt` is automatically set to `true` if no database is specified.
jwt: true,
},
}
const login = async data => {
var config = {
headers: {
'Content-Type': "application/json; charset=utf-8",
'corsOrigin': '*',
"Access-Control-Allow-Origin": "*"
}
};
const url = process.env.DATABASE_URL;
const result = await axios.post(url, data, config);
console.log('result', result);
return result;
};
export default (req, res) => NextAuth(req, res, options);

[Nuxt.JS]access the $auth object in the context from plugin js

I want to access the $auth object in the context from the js defined under 'plugins/', but I can't.
https://auth.nuxtjs.org/api/auth.html#auth
This module globally injects $auth instance, meaning that you can access it anywhere using this.$auth. For plugins, asyncData, fetch, nuxtServerInit and Middleware, you can access it from context.$auth
It is described above, but my code (axios-interceptor.js) cannot access $auth from context (it is undefined).
What does it take to be able to access it?
plugins/axios-interceptor.js
export default function (context) {
const { $axios, route, redirect } = context
$axios.interceptors.response.use(
function (response) {
return response
},
function (error) {
const code = parseInt(error.response && error.response.status)
const thisRoutePath = route.path
if ([401, 403].includes(code)) {
if (thisRoutePath !== '/') {
redirect('/?login')
}
}
return Promise.reject(error)
}
)
}
nuxt.config.js
export default {
plugins: [
'#/plugins/axios-interceptor.js'
],
modules: [
'#nuxtjs/axios',
'#nuxtjs/proxy',
'#nuxtjs/auth'
],
axios: {
baseURL: BASE_URL
},
auth: {
cookie: false,
autoFetchUser: false,
redirect: {
login: '/login',
logout: '/login',
callback: '/callback',
home: '/home'
},
strategies: {
local: {
endpoints: {
login: { url: BACKEND_API_PATH_BASE + '/api/v1/login/', method: 'post', propertyName: 'token' },
user: { url: BACKEND_API_PATH_BASE + '/api/v1/users/me', method: 'get', propertyName: false },
logout: false
},
},
}
},
router: {
middleware: [
'auth'
]
},
The reason I want to access $auth in axios-interceptor.js is that I want to execute $auth.logout() in the if ([401, 403].includes(code)) { block and remove the token.
I am now able to access $auth by doing the following
export default {
// plugins: [
// '#/plugins/axios-interceptor.js' ########### REMOVE ###########
// ],
:
(Ommit)
:
auth: {
:
(Ommit)
:
plugins: [
'#/plugins/axios-interceptor.js' // ########### ADD ###########
]
},
(Ommit)
:
}
The things I needed to do were listed below.
https://auth.nuxtjs.org/recipes/extend.html

hapi : Cannot start server before plugins finished registration

I am getting error on initial setup with Hapi and MongoDB and I am getting error after starting my server.
Code:
const Hapi = require('hapi');
var Boom = require("boom");
const dbOptions = {
url: "mongodb://localhost:27017/comparekaro",
settings: {
db: {
native_parser: false
}
}
}
const server = new Hapi.Server();
server.connection({
port : 3001,
router : {
stripTrailingSlash : true,
},
routes : {
cors : true,
}
});
server.route({
method: 'GET',
path: '/',
handler: (request, reply) => {
var db = request.server.plugins['hapi-mongodb'].db;
var ObjectID = request.server.plugins['hapi-mongodb'].ObjectID;
db.collection('catalogs').find((err, result) => {
if (err) return reply(Boom.internal('Internal MongoDB error', err));
reply(result);
});
}
});
server.route({
method: 'GET',
path: '/{name}',
handler: (request, reply) => {
reply(`i am ${request.params.name}`);
}
});
server.register({
register: require('hapi-mongodb'),
options: dbOptions
}, function (err) {
if (err) {
console.error(err);
throw err;
}
});
server.start((err) => {
if (err) {
throw err;
}
console.log(`Server running at: ${server.info.uri}`);
});
Move server.start callback inside the server.register callback, these are async operations that need to be run in a logical order.