-
Hey 👋, I'm looking for a way to authenticate users wich is not relying on an HTTP request, I'm currently using API Guard. Do you know a way to do it? Thanks for your help! |
Beta Was this translation helpful? Give feedback.
Replies: 4 comments 8 replies
-
Hello! Firstly: thanks for creating a nice framework! Secondly: I am also interested in this. In particular I have set up socket.io as described here: https://preview.adonisjs.com/blog/socketio-with-adonisjs-v5 and everything works ok. Also I can see that I can get an IncomingRequest object from socket.io as socket.request where socket is of type Socket from socket.io. So essentially we need to figure out if adonis has a function which transforms this IncomingMessage into an HttpContextContract which we then know how to use. Then we could use this function as socket.io middleware in a similar way to: https://socket.io/docs/v3/middlewares/#Compatibility-with-Express-middleware Of course if there is a completely different approach to socket auth in adonis then I'm keen to hear about that also. Many thanks, |
Beta Was this translation helpful? Give feedback.
-
I'm using API guard and I managed authentication with this function urlDecode(encoded) {
return Buffer.from(encoded, 'base64').toString('utf-8');
}
function generateHash(token) {
return crypto.createHash('sha256').update(token).digest('hex');
}
function parseToken(token) {
const parts = token.split('.');
/**
* Ensure the token has two parts
*/
if (parts.length !== 2) {
throw new Error('E_INVALID_API_TOKEN');
}
/**
* Ensure the first part is a base64 encode id
*/
const tokenId = urlDecode(parts[0]);
if (!tokenId) {
throw new Error('E_INVALID_API_TOKEN');
}
const parsedToken = generateHash(parts[1]);
return {
token: parsedToken,
tokenId,
};
}
async function checkToken(token: string): Promise<User> {
const parsedToken = parseToken(token);
const apiToken = await ApiToken.query()
.select('userId')
.where('id', parsedToken.tokenId)
.andWhere('token', parsedToken.token)
.preload('user')
.first();
if (!apiToken) {
throw new Error('E_INVALID_API_TOKEN');
}
return apiToken.user as User;
}
async function authenticate(socket: Socket): Promise<void> {
const token = socket.handshake?.query?.token;
if (!token || typeof token !== 'string') {
throw new Error(SocketErrors.MissingParameter);
}
try {
const user = await checkToken(token);
} catch (error) {
throw new Error(SocketErrors.BadCredentials);
}
}
async function connection(socket: Socket): Promise<void> {
try {
await authenticate(socket);
} catch (error) {
// handle errors
}
} |
Beta Was this translation helpful? Give feedback.
-
I am using web auth with cookie as session driver: import sessionConfig from 'Config/session'
import Encryption from '@ioc:Adonis/Core/Encryption'
import Request from '@ioc:Adonis/Core/Request'
const getSocketUser = (socket) => {
// @ts-ignore
const SocketRequest = new Request(socket.request, null, Encryption, {})
const sessionId = SocketRequest.cookie(sessionConfig.cookieName)
if(!sessionId) {
return null
}
const session = SocketRequest.encryptedCookie(sessionId)
if(!session || !session.auth_web) {
return null
}
return session.auth_web
} |
Beta Was this translation helpful? Give feedback.
-
Here's another way to authenticate in socket.io when your application has API guard. const ctx = HttpContext.create("/", {}, socket.request);
// My token is stored in an HttpOnly cookie. Update this logic as needed
const token = ctx.request.cookie(String(Env.get("API_TOKEN_COOKIE_NAME")));
ctx.request.headers().authorization = `Bearer ${token}`;
const auth = AuthManager.getAuthForRequest(ctx as any);
await auth.use("api").authenticate(); |
Beta Was this translation helpful? Give feedback.
I'm using API guard and I managed authentication with this