reflex icon indicating copy to clipboard operation
reflex copied to clipboard

Question: How to do Authentication

Open Shahin-rmz opened this issue 2 years ago β€’ 10 comments

Hello, I just wanted to know how we can handle users by Pyencone? Thanks

Shahin-rmz avatar Jan 30 '23 11:01 Shahin-rmz

There is a login example using our db see here https://github.com/pynecone-io/pynecone-examples/tree/main/twitter. We are planning on adding o auth integrations soon aswell

Alek99 avatar Jan 30 '23 20:01 Alek99

Thanks alot. I meant oAuth, and can't wait to deliver my first app using Pynecone. Thanks for developing such a needed solution.

Shahin-rmz avatar Jan 30 '23 21:01 Shahin-rmz

I'm also interessted in an OAuth solution. Are there any news since january? If it's far from being ready, is there a neat way to do it in combination with another package?

thilasx avatar Apr 17 '23 01:04 thilasx

I have done OAuth with Clerk.dev that works pretty well.


import pynecone as pc

class ClerkProvider(pc.Component):
    library = "@clerk/clerk-react"
    tag = "ClerkProvider"
    publishable_key: pc.Var[str] = "YOUR_PUBLISHABLE_KEY"
    
class SignedIn(pc.Component):
    library = "@clerk/clerk-react"
    tag = "SignedIn"

class SignedOut(pc.Component):
    library = "@clerk/clerk-react"
    tag = "SignedOut"

class SignIn(pc.Component):
    library = "@clerk/clerk-react"
    tag = "SignIn"

class UserButton(pc.Component):
    library = "@clerk/clerk-react"
    tag = "UserButton"
    
clerk_provider = ClerkProvider.create
signed_in = SignedIn.create
signed_out = SignedOut.create
sign_in = SignIn.create
user_button = UserButton.create

the components wrapped your view would look something like this

def index():
    """The main page."""
    return pc.center(
        clerk_provider(
            signed_in(
                pc,text("Signed In")
            ),
            signed_out(
                pc.center(
                    sign_in(),
                    padding_top="10em",
                )
            ),
        ),
    )

Alek99 avatar Apr 17 '23 06:04 Alek99

That looks nice. Thanks for sharing that example!

We were looking for a solution including keycloak in order to host the complete auth and application ourselves. However, with your example it will be possible to create an app in no time. Thanks again! We'll give it a try.

Maybe there is something similar for keycloak. I'll take a look.

thilasx avatar Apr 17 '23 07:04 thilasx

I have done OAuth with Clerk.dev that works pretty well.

import pynecone as pc

class ClerkProvider(pc.Component):
    library = "@clerk/clerk-react"
    tag = "ClerkProvider"
    publishable_key: pc.Var[str] = "YOUR_PUBLISHABLE_KEY"
    
class SignedIn(pc.Component):
    library = "@clerk/clerk-react"
    tag = "SignedIn"

class SignedOut(pc.Component):
    library = "@clerk/clerk-react"
    tag = "SignedOut"

class SignIn(pc.Component):
    library = "@clerk/clerk-react"
    tag = "SignIn"

class UserButton(pc.Component):
    library = "@clerk/clerk-react"
    tag = "UserButton"
    
clerk_provider = ClerkProvider.create
signed_in = SignedIn.create
signed_out = SignedOut.create
sign_in = SignIn.create
user_button = UserButton.create

the components wrapped your view would look something like this

def index():
    """The main page."""
    return pc.center(
        clerk_provider(
            signed_in(
                pc,text("Signed In")
            ),
            signed_out(
                pc.center(
                    sign_in(),
                    padding_top="10em",
                )
            ),
        ),
    )

How did you achive to get the user data afterwards? In the clerk docs I found a react hook called useUser that should return the userobject, but I'm not sure how to wrap this react hook to get the info. Thanks again :)

thilasx avatar Apr 20 '23 16:04 thilasx

There should be a way to wrap hooks, we are updating the documentation on how to do this in the next couple days so keep a look out in the wrapping react section

Alek99 avatar May 03 '23 05:05 Alek99

Monitoring this thread! look forward to seeing this solution

zmrubin avatar May 03 '23 22:05 zmrubin

This should be added to pcconfig.py.

config = pc.Config(
    ...,
    frontend_packages=['@clerk/clerk-react'],
)

Also a small typo here: pc,text("Signed In"). It should be a ..

xLaszlo avatar May 06 '23 12:05 xLaszlo

Any update on how to wrap hooks? Thanks!

adrianlzt avatar Jun 29 '23 21:06 adrianlzt

I have done OAuth with Clerk.dev that works pretty well.

import pynecone as pc

class ClerkProvider(pc.Component):
    library = "@clerk/clerk-react"
    tag = "ClerkProvider"
    publishable_key: pc.Var[str] = "YOUR_PUBLISHABLE_KEY"
    
class SignedIn(pc.Component):
    library = "@clerk/clerk-react"
    tag = "SignedIn"

class SignedOut(pc.Component):
    library = "@clerk/clerk-react"
    tag = "SignedOut"

class SignIn(pc.Component):
    library = "@clerk/clerk-react"
    tag = "SignIn"

class UserButton(pc.Component):
    library = "@clerk/clerk-react"
    tag = "UserButton"
    
clerk_provider = ClerkProvider.create
signed_in = SignedIn.create
signed_out = SignedOut.create
sign_in = SignIn.create
user_button = UserButton.create

the components wrapped your view would look something like this

def index():
    """The main page."""
    return pc.center(
        clerk_provider(
            signed_in(
                pc,text("Signed In")
            ),
            signed_out(
                pc.center(
                    sign_in(),
                    padding_top="10em",
                )
            ),
        ),
    )

Fantastic work, I'm just starting to dive into reflex, and an authentication system is a deal breaker for my project. This implementation of clerk auth seems very promising, but how would you sign out a user? or access the username of the currently signed user? or assign roles to users and grant access to different pages of the web app to a given role?

Thanks in advance, I'm very excited for this πŸ˜…

schancksb avatar Oct 22 '23 00:10 schancksb

@schancksb That's what the user_button is for. You can put the button inside the signed_in. You'll get a nice looking button to sign out. It also manages all your sessions.

Once user signed in, one of the tokens in their cookies can be used to get the user info, that contains username and typically emails and a lot of other information.

On clerk dashboard, you can create organizations and add users. I'm not sure they have very fine grain access role. That's more like RBAC. But basic access differentiation should be there.

martinxu9 avatar Oct 22 '23 00:10 martinxu9

I have done OAuth with Clerk.dev that works pretty well.

import pynecone as pc

class ClerkProvider(pc.Component):
    library = "@clerk/clerk-react"
    tag = "ClerkProvider"
    publishable_key: pc.Var[str] = "YOUR_PUBLISHABLE_KEY"
    
class SignedIn(pc.Component):
    library = "@clerk/clerk-react"
    tag = "SignedIn"

class SignedOut(pc.Component):
    library = "@clerk/clerk-react"
    tag = "SignedOut"

class SignIn(pc.Component):
    library = "@clerk/clerk-react"
    tag = "SignIn"

class UserButton(pc.Component):
    library = "@clerk/clerk-react"
    tag = "UserButton"
    
clerk_provider = ClerkProvider.create
signed_in = SignedIn.create
signed_out = SignedOut.create
sign_in = SignIn.create
user_button = UserButton.create

the components wrapped your view would look something like this

def index():
    """The main page."""
    return pc.center(
        clerk_provider(
            signed_in(
                pc,text("Signed In")
            ),
            signed_out(
                pc.center(
                    sign_in(),
                    padding_top="10em",
                )
            ),
        ),
    )

Fantastic work, I'm just starting to dive into reflex, and an authentication system is a deal breaker for my project. This implementation of clerk auth seems very promising, but how would you sign out a user? or access the username of the currently signed user? or assign roles to users and grant access to different pages of the web app to a given role?

Thanks in advance, I'm very excited for this πŸ˜…

I was able to get the username with a really ugly hook-hack. I think i posted the solution on discord some time ago. I also got live 3d rendering working with converting threejs. But to be honest: I learned and switched completely to Nextjs for simple Frontend/Backend Apps and keep Python where it excels: ML. For bigger apps Next and C#(.net core). Coding in Pynecone throughout felt like playing doom on a smartfridge. It worked an was nice but limited, slow and mostly felt like a hack. If you are really out for the idea to have one language for all try Next. Its outright powerfull and supports hot reloading. It's sad but imho you need to use the right tool for the job, even if it means learning how to handle it.

thilasx avatar Oct 22 '23 00:10 thilasx

@schancksb That's what the user_button is for. You can put the button inside the signed_in. You'll get a nice looking button to sign out. It also manages all your sessions.

Once user signed in, one of the tokens in their cookies can be used to get the user info, that contains username and typically emails and a lot of other information.

On clerk dashboard, you can create organizations and add users. I'm not sure they have very fine grain access role. That's more like RBAC. But basic access differentiation should be there.

Wow, I totally missed that line, thank you very much. I will try to make something up with the cookies and the RBAC. Thanks again πŸ˜„

schancksb avatar Oct 25 '23 01:10 schancksb

I have done OAuth with Clerk.dev that works pretty well.

import pynecone as pc

class ClerkProvider(pc.Component):
    library = "@clerk/clerk-react"
    tag = "ClerkProvider"
    publishable_key: pc.Var[str] = "YOUR_PUBLISHABLE_KEY"
    
class SignedIn(pc.Component):
    library = "@clerk/clerk-react"
    tag = "SignedIn"

class SignedOut(pc.Component):
    library = "@clerk/clerk-react"
    tag = "SignedOut"

class SignIn(pc.Component):
    library = "@clerk/clerk-react"
    tag = "SignIn"

class UserButton(pc.Component):
    library = "@clerk/clerk-react"
    tag = "UserButton"
    
clerk_provider = ClerkProvider.create
signed_in = SignedIn.create
signed_out = SignedOut.create
sign_in = SignIn.create
user_button = UserButton.create

the components wrapped your view would look something like this

def index():
    """The main page."""
    return pc.center(
        clerk_provider(
            signed_in(
                pc,text("Signed In")
            ),
            signed_out(
                pc.center(
                    sign_in(),
                    padding_top="10em",
                )
            ),
        ),
    )

Fantastic work, I'm just starting to dive into reflex, and an authentication system is a deal breaker for my project. This implementation of clerk auth seems very promising, but how would you sign out a user? or access the username of the currently signed user? or assign roles to users and grant access to different pages of the web app to a given role? Thanks in advance, I'm very excited for this πŸ˜…

I was able to get the username with a really ugly hook-hack. I think i posted the solution on discord some time ago. I also got live 3d rendering working with converting threejs. But to be honest: I learned and switched completely to Nextjs for simple Frontend/Backend Apps and keep Python where it excels: ML. For bigger apps Next and C#(.net core). Coding in Pynecone throughout felt like playing doom on a smartfridge. It worked an was nice but limited, slow and mostly felt like a hack. If you are really out for the idea to have one language for all try Next. Its outright powerfull and supports hot reloading. It's sad but imho you need to use the right tool for the job, even if it means learning how to handle it.

You're right, I've been thinking about it, and it seems to be my next project, to learn JS or TypeScript and some framework for web apps development, it will have to wait a little thought. Thanks for your comment.

schancksb avatar Oct 25 '23 01:10 schancksb

Reflex now has examples such as

https://github.com/reflex-dev/reflex-examples/tree/main/local_auth

and

https://github.com/reflex-dev/reflex-examples/tree/main/google_auth


There is also an updated guide to wrapping react components that should allow most existing auth components for react to work with reflex

https://reflex.dev/docs/wrapping-react/overview/

masenf avatar Nov 27 '23 19:11 masenf