Giter Site home page Giter Site logo

mahieyin-rahmun / nextjswithdrfexample Goto Github PK

View Code? Open in Web Editor NEW
51.0 51.0 15.0 43 KB

This repository contains the code for a two-part article series that deals with connecting a Django Rest Framework backend with a Next.js + Next-Auth client with Social Authentication. In this example, we use OAuth with Google, but this can be extended to any arbitrary number of Providers.

Home Page: https://mahieyin-rahmun.medium.com/how-to-configure-social-authentication-in-a-next-js-next-auth-django-rest-framework-application-cb4c82be137

Python 49.76% Shell 0.25% TypeScript 49.99%
article django-rest-framework medium nextauth nextjs react

nextjswithdrfexample's Introduction

Hello, world.

nextjswithdrfexample's People

Contributors

mahieyin-rahmun avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

nextjswithdrfexample's Issues

Redundant exchange of "refresh token"

The refresh token of google always remains the same.

In [...nextauth].ts, when on checking access_token has expired

const [ newAccessToken, newRefreshToken, ] = await NextAuthUtils.refreshToken(token.refreshToken);

You are sending refresh_token to this function (NextAuthUtils.refreshToken) which is as follows:

namespace NextAuthUtils { export const refreshToken = async function (refreshToken) { try { const response = await axios.post( // "http://localhost:8000/api/auth/token/refresh/", UrlUtils.makeUrl( process.env.BACKEND_API_BASE, "auth", "token", "refresh", ), { refresh: refreshToken, }, ); const { access, refresh } = response.data; // still within this block, return true return [access, refresh]; } catch { return [null, null]; } }; }

This function is sending refresh_token to backend in order to refresh our access_token in database AND YOU ARE AGAIN FETCHING THE SAME REFRESH_TOKEN FROM RESPONSE and returning it back as "newRefreshToken" (in first code attachment)

I am finding it hard to grasp why you are revolving refresh token, I am more than happy to have your findings :))

Error 400: invalid_request

Hi, just tried cloning this repo and run the application. Got this error from google after clicking to sign in with google:
Error 400: invalid_request

Screenshot from 2021-05-18 12-29-07

Any advice?

How can we extend this approach to implement SSO

I have 3 different nextjs apps, I have implemented oAuth(google) using next-auth package. I don't want my users to go through the login process for every single app rather once the user has logged-in to any one of the apps, other apps would be automatically login.

Reverse for 'socialaccount_signup' not found. 'socialaccount_signup' is not a valid view function or pattern name.

I'm getting this error where I can't sign up new users using Google Sign in. (existing users can sign in).

I found this solution online: https://stackoverflow.com/a/41241934, while it did make this particular error message go away, I was still not able to login with google.

I've added this to my urlpatterns according to the tutorial: path("api/auth/", include("dj_rest_auth.urls")),, but there was no mention of adding a socialaccount_signup path.

Any help would be greatly appreciated and thank you for this tutorial!

Happy holidays!

Traceback (most recent call last):                                                                                        
    File "/.local/lib/python3.8/site-packages/django/core/handlers/exception.py", line 47, in inner response = get_response(
    request)                                                                                      
    File "/.local/lib/python3.8/site-packages/django/core/handlers/base.py", line 181, in _get_response          
	response = wrapped_callback(request, *callback_args, **callback_kwargs)                                               
    File "/.local/lib/python3.8/site-packages/django/views/decorators/csrf.py", line 54, in wrapped_view         
	return view_func(*args, **kwargs)                                                                                     
    File "/.local/lib/python3.8/site-packages/django/views/generic/base.py", line 70, in view                    
	return self.dispatch(request, *args, **kwargs)                                                                        
    File "/.local/lib/python3.8/site-packages/django/utils/decorators.py", line 43, in _wrapper                  
	return bound_method(*args, **kwargs)                                                                                  
    File "/.local/lib/python3.8/site-packages/django/views/decorators/debug.py", line 89, in sensitive_post_parameters_wrapper                                                                                                           
	return view(request, *args, **kwargs)                                                                                 
    File "/.local/lib/python3.8/site-packages/dj_rest_auth/views.py", line 54, in dispatch                       
	return super().dispatch(*args, **kwargs)                                                                              
    File "/.local/lib/python3.8/site-packages/rest_framework/views.py", line 509, in dispatch                    
	response = self.handle_exception(exc)                                                                                 
    File "/.local/lib/python3.8/site-packages/rest_framework/views.py", line 469, in handle_exception            
	self.raise_uncaught_exception(exc)                                                                                    
    File "/.local/lib/python3.8/site-packages/rest_framework/views.py", line 480, in raise_uncaught_exception    
	raise exc                                                                                                             
    File "/.local/lib/python3.8/site-packages/rest_framework/views.py", line 506, in dispatch                    
	response = handler(request, *args, **kwargs)                                                                          
    File "/.local/lib/python3.8/site-packages/dj_rest_auth/views.py", line 125, in post                          
	self.serializer.is_valid(raise_exception=True)                                                                        
    File "/.local/lib/python3.8/site-packages/rest_framework/serializers.py", line 220, in is_valid              
	self._validated_data = self.run_validation(self.initial_data)                                                         
    File "/.local/lib/python3.8/site-packages/rest_framework/serializers.py", line 422, in run_validation        
	value = self.validate(value)                                                                                          
    File "/.local/lib/python3.8/site-packages/dj_rest_auth/registration/serializers.py", line 151, in validate                                                                                                                           
	complete_social_login(request, login)                                                                                 
    File "/.local/lib/python3.8/site-packages/allauth/socialaccount/helpers.py", line 151, in complete_social_login                                                                                                                      
	return _complete_social_login(request, sociallogin)                                                                   
    File "/.local/lib/python3.8/site-packages/allauth/socialaccount/helpers.py", line 172, in _complete_social_login                                                                                                                     
	ret = _process_signup(request, sociallogin)                                                                           
    File "/.local/lib/python3.8/site-packages/allauth/socialaccount/helpers.py", line 22, in _process_signup     
	url = reverse("socialaccount_signup")                                                                                 
    File "/.local/lib/python3.8/site-packages/django/urls/base.py", line 86, in reverse                          
	return resolver._reverse_with_prefix(view, prefix, *args, **kwargs)                                                   
    File "/.local/lib/python3.8/site-packages/django/urls/resolvers.py", line 694, in _reverse_with_prefix       
	raise NoReverseMatch(msg)                                                                                  
django.urls.exceptions.NoReverseMatch: Reverse for 'socialaccount_signup' not found. 'socialaccount_signup' is not a valid view function or pattern name. 

Question: what does exactly the drfauth do?

I know that the example comes from dj-rest-auth, however i'm just not familiar with the package so i'm not sure what magic is happening behind it

when you disable the authentication below, then what does it mean? Does the token that's already retrieved by next-auth got saved in the db? how does it work behind the scene? I'm lost looking at the code please help

Thanks

class GoogleLoginView(SocialLoginView):
  authentication_classes = [] # disable authentication, make sure to override `allowed origins` in settings.py in production!
  adapter_class = GoogleOAuth2Adapter
  callback_url = "http://localhost:3000"  # frontend application url
  client_class = OAuth2Client

Two questions about this amazing project

Hi, I wish you the best. and Thank you a lot for those two amazing article on medium.com. I just have two questions about that:

  1. Why did you disable authentication_classes:
class GoogleLoginView(SocialLoginView):
    # disable authentication, make sure to override `allowed origins` in settings.py in production!
    authentication_classes = []
    adapter_class = GoogleOAuth2Adapter
    callback_url = "http://localhost:3000"  # frontend application url
    client_class = OAuth2Clien
  1. Why didn't you wrap your app like this:
function MyApp({ Component, pageProps }) {
  return (
    <Provider session={pageProps.session}>
      <Component {...pageProps} />
    </Provider>
  )
}

Handling of refresh token on DRF

Hey Mahieyin,

Thanks for your efforts to the community!

I am wondering why are you handling refreshing of access token on DRF while we can easily do this with next-auth in [...nextauth].js file.
https://next-auth.js.org/tutorials/refresh-token-rotation

Current:
You are making a call to DRF to get a refresh token

Expected:
We are already receiving refresh token on the first request, why you are not utilizing it instead you are making it from DRF at line 76

const { access_token, refresh_token } = response.data;

Looking forward to your reply ๐Ÿ˜Š

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.