Expo app aws-exports.js in production redirect url's? - expo

oauth: {
domain: 'powrapp04889517-04889517-dev.auth.eu-west-1.amazoncognito.com',
scope: [
'phone',
'email',
'openid',
'profile',
'aws.cognito.signin.user.admin',
],
redirectSignIn: 'exp://10.42.0.89:19000/--/',
redirectSignOut: 'exp://10.42.0.89:19000/--/',
responseType: 'code',
},
as you can see I am using my local IP to test the app from Expo, which redirectSignIn, redirectSignOut urls are used when the app is ready for publishing? Is it possible to use multiple urls?

Related

How to add password and username pop up for Django Swagger?

I am using drf-yasg library for the Django Swagger. I need to add the authentication on username and password level. There are three security schemes available in this library "basic", "apiKey" or "oauth2".
Is there any way I can set my credentials for swagger in my django project settings and authenticate the swagger apidocs based on that?
To have the popup for authentication in 'DRF' and also in 'SWAGGER' panel, simply add these lines of code which I arrowed to your settings.py:
'DRF' implementation
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': [
# the link you can read about
# https://stackoverflow.com/questions/51906745/django-rest-framework-logout-not-working-after-token-authentication
'rest_framework.authentication.BasicAuthentication', # <<--
'rest_framework_simplejwt.authentication.JWTAuthentication',
'rest_framework.authentication.SessionAuthentication',
],
'DEFAULT_SCHEMA_CLASS': 'rest_framework.schemas.coreapi.AutoSchema',
}
In REST_FRAMEWORK, inside the DEFAULT_AUTHENTICATION_CLASSES, (which is a list) add the
rest_framework.authentication.BasicAuthentication.
It tells the djagno to authenticate using the default authentication that djagno provides.
'SWAGGER' implementation
If you want to use it in 'SWAGGER' as well, do the below:
In SWAGGER_SETTINGS, inside the SECURITY_DEFINITIONS which is a dict, add these lines of code to implement that:
'basic': {
'type': 'basic'
},
Default 'swagger' settings would be like this:
SWAGGER_SETTINGS = {
'DOC_EXPANSION': 'list',
'APIS_SORTER': 'alpha',
'USE_SESSION_AUTH': False,
'SECURITY_DEFINITIONS': {
'Bearer': { # <<-- is for JWT access token
'type': 'apiKey',
'name': 'Authorization',
'in': 'header'
},
'basic': { # <<-- is for djagno authentication
'type': 'basic'
},
},
}
Attention that Bearer is for JWT access token. basic is for djagno authentication.
Thant you for reading!

How do I get my API with django-cors-headers working without 405 error

I can't find my answer in other posts about CORS and django. So I am asking my question here after a full day figuring out what I am doing wrong.
my frontend is VUE.js and this app is making this API call to my backend on a DigitalOcean.com app server with Django and djangoRestFramework.
fetch( 'https://someurl.ondigitalocean.app/api/user/token',
{ method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({ email: 'emai#email.com', password: 'password' }),
},
).then(function(response){
if (response.ok){
return response.json()
}
}).then(function(data) {
console.log(data)
}
)
This does a post to receive a token. This call is just for testing purpose. The API is working, for testing I use the default django browser interface and also all my units tests are OK.
I am using django-cors-headers as Middleware and added corsheaders to my 'APP' and 'MIDDLEWARE'' in my settings file.
these are my settings:
CORS_ALLOWED_ORIGINS = [
"http://maf-internet.nl",
"http://localhost:8080",
"http://127.0.0.1:8000"
]
CSRF_TRUSTED_ORIGINS = [
"http://maf-internet.nl",
]
CORS_ALLOW_ALL_ORIGINS = True
CORS_ALLOW_METHODS = [
'DELETE',
'GET',
'OPTIONS',
'PATCH',
'POST',
'PUT',
]
CORS_ALLOW_HEADERS = [
'accept',
'accept-encoding',
'authorization',
'content-type',
'dnt',
'origin',
'user-agent',
'x-csrftoken',
'x-requested-with',
]
These are my packages:
Django>= 2.2, <2.2.2
djangorestframework>=3.9.0,<3.10.0
psycopg2-binary
dj-database-url
gunicorn
django-cors-headers>=3.7.0
flake8>=3.6.0,<3.7.0
Digital Ocean also has an entry for CORS origin. I have added the front-end domain here and the result is still the same. Here you see my error 405.
I just don't see what I am doing wrong. What could be the problem?
Solved, I had to protect the client domain with https. I did not know, and for testing I thought it would be fine to use a HTTP domain. Wrong! You need an Https domain to talk to django-rest-framework and django-cors-headers on DigitalOcena app's.
You can use this django-cors-headers library to solve your issue.
tried pip install django-cors-middleware and worked for me without having to do any thing , just make sure you have 'corsheaders.middleware.CorsMiddleware' in your MIDDLEWARE

django-rest-auth google and facebook sign up returning access token and code

I am building a rest api with Django, and I an using Django rest auth for social authentication. I believe I am doing everything right. upon visiting the route I get a response that I am to provide both access token and code for both Google and Facebook. I am lost at this point what to do. Please anyone who has an idea, please share.
I have gotten the secret key and client id from both providers and inputed them in my settings.py and django admin.
settings.py
INSTALLED_APPS = [
...
'django.contrib.sites',
...
'rest_auth',
'rest_auth.registration',
'allauth',
'allauth.account',
'allauth.socialaccount',
'allauth.socialaccount.providers.google',
'allauth.socialaccount.providers.facebook',
...
]
SOCIALACCOUNT_PROVIDERS = {
'facebook': {
'METHOD': 'oauth2',
'SCOPE': ['email', 'public_profile', 'user_friends'],
'AUTH_PARAMS': {'auth_type': 'reauthenticate'},
'INIT_PARAMS': {'cookie': True},
'FIELDS': [
'id',
'email',
'name',
'first_name',
'last_name',
'verified',
'locale',
'timezone',
'link',
'gender',
'updated_time',
],
'EXCHANGE_TOKEN': True,
'LOCALE_FUNC': 'path.to.callable',
'VERIFIED_EMAIL': True,
'VERSION': 'v2.12',
'APP': {
# get the key from "https://developers.facebook.com/apps/615248019004301/settings/basic/"
'client_id': 'code',
'secret': 'code',
'key': ''
}
},
'google': {
'SCOPE': [
'profile',
'email',
],
'AUTH_PARAMS': {
'access_type': 'offline',
},
'APP': {
# get from "console.developers.google.com/" then apis then credentials then oauthclient
# fill in http://127.0.0.1:8000/accounts/google/login/callback/ in the “Authorized redirect URI” field
'client_id': 'code.apps.googleusercontent.com',
'secret': 'code',
'key': ''
}
}
}
SITE_ID = 1
SOCIALACCOUNT_ADAPTER = "allauth.socialaccount.adapter.DefaultSocialAccountAdapter"
SOCIALACCOUNT_EMAIL_REQUIRED = ACCOUNT_EMAIL_REQUIRED
OK I'm in a similar situation and have been doing a lot of reading. Looks like you have performed all the setup correctly. And now you are trying to perform signup / login via your API from a client.
I'm going to make some assumptions as you don't provide a lot in your question by way of detail. For instance, I'm not sure what route you are visiting, or, what kind of an API client (DRF browseable API, React frontend, mobile app?) you are using. That said, it shouldn't really matter what kind of client you use, the process should be the same.
Here are the steps:
You will need to initiate signup / login from your API client either by rolling your own code or using whatever libraries are available for the technology you are using. For instance, Facebook provides its own JavaScript SDK. If you are using React, you could use react-facebook-login. Note that I've personally used neither so YMMV.
On successful authentication, at Facebook for instance, you will get a accessToken, which your client should send to your API at /rest-auth/facebook/ (or whatever you have configured in your urls.py).
When this flow happens, a new user should be created in your backend with all their details.
Here is an example blog post that I found where the author shows this flow for a React frontend application: https://medium.com/#pratique/social-login-with-react-and-django-ii-39b8aa20cd27.
Here is another example of a similar flow I found on SO. In the answer, the user is using the python-social-auth package instead of django-allauth but the flow is similar: https://stackoverflow.com/a/46476631/399435.
Since your client will be making requests to your API, I believe that you will also have to setup CORS correctly for such requests to succeed.
Hope that points you in the right direction. I'm going to be attempting this myself soon and if I learn that something is different, I will get back to edit this answer.
As far as I understand, the problem it's that are you sending a GET request, when the login view only accept a POST request. You must change the method.

Django REST Swagger with OAuth2 authentication

I have a REST API created with Django rest framework. To authenticate my API calls I am using OAuth2 tokens. My question is how can I enable standard username/password authentication in docs generated by Django rest swagger.
Right now i am gettings
401 : {"detail":"Authentication credentials were not provided."} http://127.0.0.1:8000/docs/?format=openapi
settings
REST_FRAMEWORK = {
# Don't perform any authentication on API calls so we don't have any CSRF problems
# :PRODUCTION: Put back authentication for production version when not testing on same server?
'DEFAULT_AUTHENTICATION_CLASSES': [
'oauth2_provider.ext.rest_framework.OAuth2Authentication',
'rest_framework_social_oauth2.authentication.SocialAuthentication',
],
'DEFAULT_PERMISSION_CLASSES': [
'rest_framework.permissions.IsAuthenticated',
],
'PAGE_SIZE': 1000, # Max number of results returned from a list API call
'DEFAULT_FILTER_BACKENDS': ('rest_framework.filters.DjangoFilterBackend',),
# Use JSONRender so the Web API interface is not shown. This is needed when testing the app on the same server
'DEFAULT_RENDERER_CLASSES': (
'rest_framework.renderers.JSONRenderer',
)
}
SWAGGER_SETTINGS = {
'SECURITY_DEFINITIONS': {
'veeu': {
'type': 'oauth2',
'flow': 'password',
'tokenUrl': 'http://localhost:8000/auth/token/',
'scopes': {
'write:all': 'Write all',
'read:all': 'Read all',
}
}
},
}
LOGIN_URL = 'http://localhost:8000/admin/'
When I click Django login it takes me to admin login page. And after I log in, this message is still the same. If I add header Authorization: Bearer TokenHere it works. However, the point is to enable username/password login.
To access Swagger documentation, you need SessionAuth with the following in the settings.py :
# API VERSIONING
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': [
'rest_framework.authentication.SessionAuthentication',
'oauth2_provider.contrib.rest_framework.OAuth2Authentication',
],
'DEFAULT_PERMISSION_CLASSES': [
'rest_framework.permissions.IsAuthenticated'
],
}
This allows you to access Swagger generated documentation. Problem is, whatever endpoint you have protected with OAuth2 won't be visible via Swagger, at least if you are generating OAuth via "application". The following code does not work at all and I'm linking the thread discussed asking for anyone to work on that feature:
# TODO Swagger implementation is not working for password since
# it sends client_id and client_secret as query strings and not as
# user separated with "::"
# The "application" flow setting also that does work
#
SWAGGER_SETTINGS = {
'SUPPORTED_SUBMIT_METHODS': [], # Due to bug described above
'SECURITY_DEFINITIONS': {
"customers_auth": {
"type": "oauth2",
"tokenUrl": "/o/token/",
"flow": "password",
"scopes": {
"read": "Read scope",
"write": "Write scope"
}
}
},
}

how to add token auth to swagger + django rest framework?

I am using both great tools DRF and Django-REST-Swagger, however a few of my API views are under token authentication.
So now I'd like to add to my swagger doc page of my API the possibility to test those token auth api urls, including the Token header. How could I do this?.
A snapshot of my class API view is like this:
class BookList(APIView):
"""
List all books, or create a new book.
"""
authentication_classes = (TokenAuthentication, )
permission_classes = (IsAuthenticated,)
...
Since Swagger auto detects a lot of stuff, I was expecting to notice about token auth, and ask me about token or user id in its web interface, but it doesn't. Hence I am testing it manually through CURL commands...
If you're using token authentication, you might want to look at this question
Basically, you just need to add this to your settings.py:
SWAGGER_SETTINGS = {
'SECURITY_DEFINITIONS': {
'api_key': {
'type': 'apiKey',
'in': 'header',
'name': 'Authorization'
}
},
}
In your Swagger UI page you should see an Authorize button. Click that and enter your Authorization value in the input text field.
I answer myself since I made it work.
Actually Swagger settings has an option for this, api_key ->
SWAGGER_SETTINGS = {
"exclude_namespaces": [], # List URL namespaces to ignore
"api_version": '0.1', # Specify your API's version
"api_path": "/", # Specify the path to your API not a root level
"enabled_methods": [ # Specify which methods to enable in Swagger UI
'get',
'post',
'put',
'patch',
'delete'
],
"api_key": '', # An API key
"is_authenticated": False, # Set to True to enforce user authentication,
"is_superuser": False, # Set to True to enforce admin only access
}
To me it wasn't that clear, but I've just input a valid token for testing user and it worked for the auth needed views :-)
My Problem was that after activating TokenAuthentification my api urls were not shown any more in the swagger UI due to an AuthentificationError.
For me the solution was to activate both authentaction classes in the Django Rest Framework Settings:
SessionAuthentification -> for the Swagger UI
TokenAuthentification -> for the Rest Clients
REST_FRAMEWORK = {
'DEFAULT_PERMISSION_CLASSES': ('rest_framework.permissions.IsAdminUser',),
'DEFAULT_AUTHENTICATION_CLASSES': (
'rest_framework.authentication.TokenAuthentication',
'rest_framework.authentication.SessionAuthentication'
)
}
The schema view needs to have the permission of AllowAny. This allows the plugin to see which endpoints are available before the user has authenticated. The end points should still be protected if they are setup correctly. Example:
#api_view()
#renderer_classes([SwaggerUIRenderer, OpenAPIRenderer, renderers.CoreJSONRenderer])
#authentication_classes((TokenAuthentication, SessionAuthentication))
#permission_classes((AllowAny,))
def schema_view(request):
generator = schemas.SchemaGenerator(
title='My API end points',
patterns=my_urls,
url="/api/v1/")
return response.Response(generator.get_schema(request=request))
It is best to remove the SessionAuthentication and only use the TokenAuthentication but that is a matter of choice, here I have removed it
REST_FRAMEWORK = {
'DEFAULT_PERMISSION_CLASSES': [
'rest_framework.permissions.IsAuthenticated'
'DEFAULT_AUTHENTICATION_CLASSES': (
'rest_framework.authentication.TokenAuthentication'
)
Be sure it add 'rest_framework.authtoken' into your installed apps and remove the CsrfViewMiddleware from the middleware classes as it will no longer be needed. And the swagger settings
SWAGGER_SETTINGS = {
'SECURITY_DEFINITIONS': {
'api_key': {
'type': 'apiKey',
'in': 'header',
'name': 'Authorization'
}
},
'USE_SESSION_AUTH': False,
'JSON_EDITOR': True,
}
This will make swagger populate the token into all of the example curl commands as well, which is really nice to have. Leaving the session auth in place seems to disable this.
The swagger authorization dialog asks for the api_key which needs to be provided. Can not seem improve this, will update this post if I do.
just add to you rest framework setting SessionAuthentication should be at the top
'DEFAULT_AUTHENTICATION_CLASSES': (
'rest_framework.authentication.SessionAuthentication',
'mymodule.authentication.CustomeAuthentication',
)
Note: SessionAuthentication will use your Django login session
CustomeAuthentication will be used for rest api for real use case.
if you are implementing the answer of #Melvic Ybanez with django-rest-swagger==2.2.0 and still doesn't work. Downgrade to django-rest-swagger==2.1.2.
Button authorize should work now.
I manage to change Swagger's default basic authentication to token authentication with this configuration but when try me button is pressed rest swagger accepts any authentication regardless of valid token.
Also note, when I added SessionAuthentication to my REST_FRAMEWORK in my settings.py, my api failed to be displayed on swagger docs.
django-rest-swagger==2.2.0
djangorestframework==3.7.7
settings.py
INSTALLED_APPS = [
'rest_framework',
'rest_framework_swagger',
'rest_framework.authtoken',
]
REST_FRAMEWORK = {
# Parser classes priority-wise for Swagger
'DEFAULT_PARSER_CLASSES': [
'rest_framework.parsers.FormParser',
'rest_framework.parsers.MultiPartParser',
'rest_framework.parsers.JSONParser',
'rest_framework.authentication.TokenAuthentication',
],
'DEFAULT_AUTHENTICATION_CLASSES': (
'rest_framework.authentication.TokenAuthentication',
)
}
# SWAGGER SETTINGS
SWAGGER_SETTINGS = {
'SECURITY_DEFINITIONS': {
'api_Key': {
'type': 'apiKey',
'in': 'header',
'name': 'Token Authorization'
}
},
}
some helpful documentation https://github.com/OAI/OpenAPI-Specification/blob/master/versions/2.0.md#security-definitions-object
Please use rest_framework_jwt.authentication.JSONWebTokenAuthentication instead of rest_framework.authentication.TokenAuthentication.
My code is
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': (
'rest_framework_jwt.authentication.JSONWebTokenAuthentication',
# 'rest_framework.authentication.TokenAuthentication',
),
'DEFAULT_PARSER_CLASSES': (
'rest_framework.parsers.FormParser',
'rest_framework.parsers.MultiPartParser',
'rest_framework.parsers.JSONParser',
),
}
AUTH_USER_MODEL = 'auth.User'
JWT_AUTH = {
'JWT_ENCODE_HANDLER':
'rest_framework_jwt.utils.jwt_encode_handler',
'JWT_DECODE_HANDLER':
'rest_framework_jwt.utils.jwt_decode_handler',
'JWT_PAYLOAD_HANDLER':
'rest_framework_jwt.utils.jwt_payload_handler',
'JWT_PAYLOAD_GET_USER_ID_HANDLER':
'rest_framework_jwt.utils.jwt_get_user_id_from_payload_handler',
'JWT_RESPONSE_PAYLOAD_HANDLER':
'rest_framework_jwt.utils.jwt_response_payload_handler',
'JWT_SECRET_KEY': SECRET_KEY,
'JWT_ALGORITHM': 'HS256',
'JWT_VERIFY': True,
'JWT_VERIFY_EXPIRATION': True,
'JWT_LEEWAY': 0,
'JWT_EXPIRATION_DELTA': datetime.timedelta(seconds=86400),
'JWT_AUDIENCE': None,
'JWT_ISSUER': None,
'JWT_ALLOW_REFRESH': True,
'JWT_REFRESH_EXPIRATION_DELTA': datetime.timedelta(days=1),
'JWT_AUTH_HEADER_PREFIX': 'Bearer',
}
SWAGGER_SETTINGS = {
'SHOW_REQUEST_HEADERS': True,
'SECURITY_DEFINITIONS': {
'Bearer': {
'type': 'apiKey',
'name': 'Authorization',
'in': 'header'
}
},
'USE_SESSION_AUTH': False,
'JSON_EDITOR': True,
'SUPPORTED_SUBMIT_METHODS': [
'get',
'post',
'put',
'delete',
'patch'
],
}
I solved the problem.