elysiajs / elysia

Ergonomic Framework for Humans
https://elysiajs.com
MIT License
9.8k stars 208 forks source link

How to get client ip? #230

Closed xfxpositions closed 1 week ago

xfxpositions commented 11 months ago

i'm trying to find something like this from koajs

const client_ip =
ctx.req.ip ||
ctx.req.headers["x-forwarded-for"] ||
ctx.req.connection.remoteAddress;
masfahru commented 11 months ago

i think client ip should be available after this PR https://github.com/oven-sh/bun/pull/6165 is done

bogeychan commented 11 months ago

Hi 👋

since Bun v1.0.4 you can do something like this:

import { Elysia } from 'elysia';

const app = new Elysia();

app
  .derive((ctx) => ({
    remoteAddress: () => app.server!.requestIP(ctx.request)
  }))
  .get('/', (ctx) => ctx.remoteAddress())

  .listen(3000);

console.log(`Listening on http://${app.server!.hostname}:${app.server!.port}`);

Response:

{
    "address": "::1",
    "family": "IPv6",
    "port": 40908
}
juancwu commented 11 months ago

Is there a plan to add the IP to the context request object by default? If not, I am down to try to add it. I am relatively new here but I am sure it shouldn't be too hard.

Please let me know if having it in the context request object is desired or not :)

gaurishhs commented 11 months ago

You can use https://github.com/gaurishhs/elysia-ip

cassinius commented 11 months ago

Thank you for providing this library, it works well on the main Elysia app instance ;-)

However, if I try to use this in a plugin, I get

null is not an object (evaluating '<plugin>.server.requestIP')

Is there any way to make this work in a specific plugin only ?

gaurishhs commented 11 months ago

that means the server isn't up yet, Try to use the plugin inside an Elysia app instance and call the .listen method, It should work well. Currently, You don't seem to call .listen

cassinius commented 11 months ago

I am calling .listen on the main Elysia app instance, here is my code:

import { Elysia } from "elysia";
import { ip } from "elysia-ip";

const plugin = new Elysia()
  .use(ip())
  .get("/ip-from-plugin", ({ ip }) => ip);

const app = new Elysia()
  .use(ip())
  .get("/ip", ({ ip }) => ip)
  .use(plugin)
  .listen(3000);

Here, /ip works as expected, /ip-from-plugin throws the error. If I call .listen() on the plugin as well, like

const plugin = new Elysia()
  .use(ip())
  .get("/ip-from-plugin", ({ ip }) => ip)
  .listen(3001);

it actually DOES work, but I doubt that's how it's meant to be used?

P.S. removing the ip-related lines from the main instance does not make a difference.

gaurishhs commented 11 months ago

I am facing the same, i don't really know the reason behind the same. I believe its somehow related to how plugins work in Elysia

gaurishhs commented 11 months ago

@cassinius Hi, i seem to have found a fix for the same. Not initalizing the ip in plugin seems to work.

import { Elysia } from "elysia";
import { ip } from "elysia-ip";

const plugin = new Elysia()
  // .use(ip())
  .get("/ip-from-plugin", ({ ip }) => ip);

const app = new Elysia()
  .use(ip())
  .get("/ip", ({ ip }) => ip)
  .use(plugin)
  .listen(3000);

The autocomplete is not there for some reason in plugin and there on the app instance which doesn't really make sense to me (It's probably related to how .derive works). I reached out to salty for further help.

xfxpositions commented 11 months ago
// getting request ip
app.use(ip());
TypeError: undefined is not an object (evaluating 'request.headers')

not working

gaurishhs commented 11 months ago

Can you share your complete code and how youre making the request. The headers shouldnt be undefined though.

On Fri, 6 Oct, 2023, 20:18 xfxpositions, @.***> wrote:

// getting request ipapp.use(ip());

TypeError: undefined is not an object (evaluating 'request.headers')

not working

— Reply to this email directly, view it on GitHub https://github.com/elysiajs/elysia/issues/230#issuecomment-1750809737, or unsubscribe https://github.com/notifications/unsubscribe-auth/ASZRZB75MJIQQWDZBHUHBDLX6AK5FAVCNFSM6AAAAAA5IALIBCVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMYTONJQHAYDSNZTG4 . You are receiving this because you commented.Message ID: @.***>

SaltyAom commented 1 week ago

Close as elysia-ip plugin and server property is now implemented in Elysia 1.1

You can natively get IP from Elysia request like this, make sure server is running:

new Elysia()
    .get('/', ({ server, request }) => {
        server?.requestIP(request)
    })
        .listen(3000)