adonisjs/adonis-websocket

How can I get current logged in user details in controller?

Closed this issue · 12 comments

I am trying to get the current user from the socket controller.

Trying to get it like this
`constructor ({ socket, request , auth, session}) {
this.socket = socket
this.request = request
this.auth=auth

}
async onClose (data) {
const user = await this.auth.user
console.log(user) // it gives null
}`

Also tried to get some values from session. Sessions works in all controller except here.
Any ways I can get the user id from here?

Many thanks.

  1. Please format your codeblocks properly. Here's the markdown guide
  2. Share code for start/kernel.js
  3. Share code on how you connect from the client side.

Also, please create proper issues, otherwise they will be closed in the future.

HI, Thank you so much for your valuable time :)

I think I have the default code from start/kernel.js . Here is the code without comments

'use strict'

const Server = use('Server')
const globalMiddleware = [
  'Adonis/Middleware/BodyParser',
  'Adonis/Middleware/Session',
  'Adonis/Middleware/Shield',
  'Adonis/Middleware/AuthInit'
]
const namedMiddleware = {
  auth: 'Adonis/Middleware/Auth'
}
const serverMiddleware = [
  'Adonis/Middleware/Static',
  'Adonis/Middleware/Cors'
]

Server
  .registerGlobal(globalMiddleware)
  .registerNamed(namedMiddleware)
  .use(serverMiddleware)

I am using adonuxt. All other socket related things are working nicely. Just need the logged in user data.
Here is how I am connecting.

    const myRoom=this.authUser.id
    const ws = adonis.Ws()
    ws.connect()
    // subscribe to topic that are coming for me
    const chat = ws.subscribe(`noti:${id}`)
    chat.on('error', (error) => {
        console.log(error)
      })

     ws.getSubscription(`noti:${id}`).on('message', (msg) => {
           console.log(msg) 
           // many more code here and all works fine...
     })
     

My socket route is like this

const Ws = use('Ws')
Ws.channel('noti:*', 'NotifyerController')

And in my NotifyerController I have

'use strict'
const notiClass = use('App/classes/notification')
const noti = new notiClass()
class ChatController  {
  constructor ({ socket, request, auth}) {
     this.socket = socket
     this.request = request
     this.auth = auth // this doesn't work. 
  }
  async onClose (data) {
        // here I am trying to get the user id so that I can make database query to make this user offline.
  }

}

What scheme are you using for authentication?

The default one. Sessions (session).

Kind of weird. Lemme try to reproduce the issue and update you

Thank you so much..

Any update on it? If you could at least show an example how you would have done this

How to know which user is disconnected from the subscribed topic or in any other way.

Waiting for a help. Thank you so much for this great work.

I believe I may be getting a similar issue:

wsKernel.js

'use strict'

const Ws = use('Ws')

const globalMiddleware = [
  'Adonis/Middleware/Session',
  'Adonis/Middleware/AuthInit'
]


const namedMiddleware = {
  auth: 'Adonis/Middleware/Auth',
  guest: 'Adonis/Middleware/AllowGuestOnly',
}

Ws
  .registerGlobal(globalMiddleware)
  .registerNamed(namedMiddleware)

socket.js

const Ws = use('Ws')

Ws.channel('report', 'ReportController').middleware('auth')
Ws.channel('authentication', 'AuthenticationController')

and finally in AuthenticationController.js

  async onLoginAs(message){
    var user = ...;// My special login/search function
    if(user){
      this.auth.login(user);
      this.socket.emit('login-success',{user})
    }else{
      this.socket.emit('login-failed',true)
    }
  }

When user is found, the following error occurs:

[0] warning: 
[0]   WARNING: Adonis has detected an unhandled promise rejection, which may
[0]   cause undesired behavior in production.
[0]   To stop this warning, use catch() on promises or wrap await
[0]   calls inside try/catch.
[0] 
[0] RuntimeException: E_RUNTIME_ERROR: Session store is freezed and you cannot write values to session. This usually happens during the Websocket request
[0] > More details: https://err.sh/adonisjs/errors/E_RUNTIME_ERROR
[0]     at Function.invoke (/Users/me/Sites/myproject/site/node_modules/@adonisjs/generic-exceptions/src/RuntimeException.js:102:12)
[0]     at Session._ensureNotFreezed (/Users/me/Sites/myproject/site/node_modules/@adonisjs/session/src/Session/index.js:129:10)
[0]     at Session.put (/Users/me/Sites/myproject/site/node_modules/@adonisjs/session/src/Session/index.js:214:10)
[0]     at SessionScheme._setSession (/Users/me/Sites/myproject/site/node_modules/@adonisjs/auth/src/Schemes/Session.js:88:23)
[0]     at SessionScheme.login (/Users/me/Sites/myproject/site/node_modules/@adonisjs/auth/src/Schemes/Session.js:228:10)
[0]     at AuthenticationController.onLoginAs (/Users/me/Sites/myproject/site/app/Controllers/Ws/AuthenticationController.js:23:17)

EDIT: After reviewing, it would appear this is to SET the current logged in user (still a bug, but not THIS bug which is about getting the current user)

I am trying to get the current user from the socket controller.

Trying to get it like this
`constructor ({ socket, request , auth, session}) {
this.socket = socket
this.request = request
this.auth=auth

}
async onClose (data) {
const user = await this.auth.user
console.log(user) // it gives null
}`

Also tried to get some values from session. Sessions works in all controller except here.
Any ways I can get the user id from here?

Many thanks.

I had this same issue. I just had to add the Auth Middleware in the wsKernel.js file.

`'use strict'

const Ws = use('Ws')

const globalMiddleware = [
'Adonis/Middleware/Session',
'Adonis/Middleware/AuthInit'
]

const namedMiddleware = {
auth: 'Adonis/Middleware/Auth'
}

Ws
.registerGlobal(globalMiddleware)
.registerNamed(namedMiddleware)`

HI, where did you write your onLoginAs method? In socket controller or normal http controller?

It's working for me now.
I think my problem was, I was using
const globalMiddleware = [ 'Adonis/Middleware/Session', 'App/Middleware/Auth' ]

Now I changed it to
const globalMiddleware = [ 'Adonis/Middleware/Session', 'Adonis/Middleware/AuthInit' ]

And also in socket.js I am using Ws.channel('noti:*', 'NotifyerController').middleware('auth')

Yup, this is it!

Glad you fixed it 🤗

Closing then.