Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Idea] Authentication example #325

Closed
vassbence opened this issue Mar 31, 2020 · 16 comments
Closed

[Idea] Authentication example #325

vassbence opened this issue Mar 31, 2020 · 16 comments
Labels
example Changes related to examples

Comments

@vassbence
Copy link
Contributor

vassbence commented Mar 31, 2020

Hello!

After a few people have already mentioned over at the Next.js repo that Zeit uses SWR for handling authentication on for example the /dashboard page of zeit.co I think a simple example would interest a lot of people, myself included.

This I think would need a bigger scale example, like a whole Next.js starter with some /api endpoints (skipping on the actual implementation and just returning a placeholder cookie etc.).

@vassbence vassbence changed the title [Idea] Auth example [Idea] Authentication example Mar 31, 2020
@shuding shuding added the example Changes related to examples label Mar 31, 2020
@shuding
Copy link
Member

shuding commented Mar 31, 2020

For sure @vassbence 👍 I've been working on a realworld example for a while. It covers a lot of use cases including authentication just like you said. Stay tuned!

@Manubi
Copy link

Manubi commented Apr 6, 2020

Looking forward to more examples. Also more graphql related things as it quickly gets messy if you don't use REST.

@darbio
Copy link

darbio commented May 14, 2020

For bearer authentication I use the following:

<SWRConfig
    value={{
        fetcher: async (url) => {
            const res = await fetch(url, {
                headers: {
                    'Content-Type': 'application/json',
                    Authorization: `Bearer ${state.tokens?.access}`,
                },
            });
            return res.json();
        },
    }}
>
    {children}
</SWRConfig>

@stunaz
Copy link

stunaz commented May 15, 2020

@darbio Error handling? Login Redirect? Redirect to the current page after refresh? refetch? ...

@danilockthar
Copy link

Hope they made the example!

@Manubi
Copy link

Manubi commented May 18, 2020

For sure @vassbence 👍 I've been working on a realworld example for a while. It covers a lot of use cases including authentication just like you said. Stay tuned!

any news? :)

@darbio
Copy link

darbio commented May 31, 2020

@darbio Error handling? Login Redirect? Redirect to the current page after refresh? refetch? ...

These are handled outside of the fetcher because the responsibility of the fetcher is to fetch, and not handle authentication.

@stunaz
Copy link

stunaz commented May 31, 2020

@darbio so what do you do when you fetch and you get a 401?

@sergiodxa
Copy link
Contributor

I throw an error and catch it with an Error Boundary and redirect there

@vassbence
Copy link
Contributor Author

@darbio Error handling? Login Redirect? Redirect to the current page after refresh? refetch? ...

https://github.com/vercel/next.js/blob/canary/examples/with-iron-session/lib/useUser.js

This is a good example made for next.js, it is even using SWR

@darbio
Copy link

darbio commented Jun 2, 2020

@darbio so what do you do when you fetch and you get a 401?

I don't - the refreshing of tokens and logging in etc. is managed by my Authentication service (which, irrelevantly, is Cognito via Amplify). If the user gets to a point where they are getting a 401 they are doing "somethingDodgy" ^TM.

If I needed to handle 401's I would throw an NotAuthorizedError and handle at the application error boundary to perform a refresh and redirect to the page as @sergiodxa suggested. Something along the lines of:

<SWRConfig
    value={{
        fetcher: async (url) => {
            const res = await fetch(url, {
                headers: {
                    'Content-Type': 'application/json',
                    Authorization: `Bearer ${state.tokens?.access}`,
                },
            });
            if (!res.ok()) {
                if (res.statusCode === 401) throw new NotAuthorizedError(res.statusMessage);
                else throw new Error(res.statusMessage);
            }
            return res.json();
        },
    }}
>
    {children}
</SWRConfig>

I like the sample provided by @vassbence and I might experiment with that. My original statement of it not being the responsibility of the fetcher to handle this, remains my opinion. And you know what they say about opinions :)

My example is not meant to cover all bases, but it does show how I use it in a (relatively simple) example. YMMV.

@vvo
Copy link
Member

vvo commented Jun 3, 2020

Hey there, I was planning to jump in here but @vassbence beat me to it: if you're looking for a Next.js authentication system using SWR that is similar to the one from https://vercel.com/dashboard then https://github.com/vvo/next-iron-session could be one way to do it. Everything is detailed in the README and if you're having trouble with the package just open issues on the project, thanks!

@maxcountryman
Copy link

For sure @vassbence 👍 I've been working on a realworld example for a while. It covers a lot of use cases including authentication just like you said. Stay tuned!

Would love to see this. 🙂

@vassbence
Copy link
Contributor Author

For sure @vassbence 👍 I've been working on a realworld example for a while. It covers a lot of use cases including authentication just like you said. Stay tuned!

Would love to see this. 🙂

https://swr.vercel.app/examples/auth

@plaa
Copy link

plaa commented Apr 12, 2021

I think this example specifically demonstrates incorrect usage as explained here https://swr.vercel.app/docs/arguments#multiple-arguments

For caching to work properly, the fetcher method must be pure (insofar as the corresponding server API is), and the authentication information should be passed in the key. The example's fetch method changes behavior depending on cookies, and thus the caching will break.

The only reason the example "works" is that the user is hard-coded. If you change it to return different values different times, the caching will kick in and the user info is never refreshed.

@danielweil
Copy link

For bearer authentication I use the following:

<SWRConfig
    value={{
        fetcher: async (url) => {
            const res = await fetch(url, {
                headers: {
                    'Content-Type': 'application/json',
                    Authorization: `Bearer ${state.tokens?.access}`,
                },
            });
            return res.json();
        },
    }}
>
    {children}
</SWRConfig>

Where does the state variable come from?
Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
example Changes related to examples
Projects
None yet
Development

No branches or pull requests