I would like to embed my Django website in a specific external website (not any website).
For example, my website is https://www.mywebsite.com and would like to include it in an other website (https://www.example.com) with an iframe like this:
<iframe
src="https://www.mywebsite.com">
</iframe>
I read a lot of docs and I don't understand if I have to use django-csp or X_FRAME_OPTIONS (which seems depreciated), or both to be compatible with every navigators.
I tried to install and setup django-csp but in that case all of the ressources are blocked.
CSP_DEFAULT_SRC = ("'none'", 'https://example.com')
CSP_STYLE_SRC = ("'self'" )
CSP_SCRIPT_SRC = ("'self'" )
CSP_IMG_SRC = ("'self'" )
CSP_FONT_SRC = ("'self'" )
Here is the configuration : Django + REST Framework + React
Thanks a lot!
Use the CSP_FRAME_ANCESTORS policy setting. Update the tuple to include "https://example.com" which is the hostname of your REACT frontend.
CSP_FRAME_ANCESTORS=["https://example.com"]
This policy setting does not use default-src as a fallback which is the reason why your configuration did not allow for iframing.
Related
I'm trying to embed Superset (version 1.3) in an iframe and I'm getting a DOMException 18. The installation of Superset itself works fine since I can access it normally at its URL. Ultimately, my need is to allow website X of a completely different origin to embed a view of my superset instance.
I've found a number of github issues and articles online suggesting changes to superset_config.py to allow embedding superset in an iframe and I've made a few of them. In particular, I've made the following changes to config.py (rather than superset_config.py as a temporary measure to be sure that the config changes were indeed being registered):
from .mysecurity import CustomSecurityManager
CUSTOM_SECURITY_MANAGER = CustomSecurityManager
ENABLE_PROXY_FIX = True
HTTP_HEADERS: Dict[str, Any] = {'X-Frame-Options': 'ALLOWALL'}
SESSION_COOKIE_SECURE = True
SESSION_COOKIE_SAMESITE = "None"
I'm using a this as a base for custom security manager (the only changes are that I'm checking a token against another service before logging in the user and I'm providing a redirect in the URL).
This instance of superset is behind NGINX which is setting Access-Control-Allow-Origin * and running with gunicorn.
The following screenshots are from my local host with a basic website that has the following bit of relevant JS logging in a user with role Gamma:
let analytics_div = document.getElementById('analytics');
let report = document.createElement("iframe")
const report_url = new URL("/superset/dashboard/123/?standalone=true", superset_url);
const start_url = new URL(`/login?auth_code=${superset_auth_token}&redirect=${report_url}`, superset_url)
report.src = start_url;
report.width = "100%"
report.height = 700
analytics_div.appendChild(report)
Error I'm getting in the iframe
What I see in the dev tools
I made an Angular application able use an online api to get a json and do stuff.
But, although the json is the same, if I try to change only the url of the json by setting a local url of a server written in django, angular would seem not to connect anymore ...
My question is, why if with an online cloud server works, with a local one wouldn't?
I tried making this server "on cloud" opening the router's port, also setting up a ddns, and using postman or a browser it seems to work, but when i try to connect with angular it still doesn't get the data...
I am sure 100% that the server answer, with the right json data, because django prints on console that he received a HTTP GET request :
http://i.imgur.com/TIQnIcR.png
I remind you that the HTTP angular request worked with another api, but i will still show up some code :
export class ProdottoService {
private prodotti: Array<ProdottoModel>;
constructor(private httpClient: HttpClient) {
this.prodotti = new Array<ProdottoModel>();
var url:string = "https://gist.githubusercontent.com/saniyusuf/406b843afdfb9c6a86e25753fe2761f4/raw/523c324c7fcc36efab8224f9ebb7556c09b69a14/Film.JSON";
var local_url:string = "http://127.0.0.1:8000/films/?format=json";
httpClient.get(local_url)
.subscribe((films : Array<Object> ) => {
films.forEach((film => {
this.prodotti.push(new ProdottoModel(film));
}));
}
);
}
getProdotti(): Array<ProdottoModel> {
return this.prodotti;
}
}
Result using external api :
http://i.imgur.com/MT7xD9c.png
Thanks in advace for any help :3
-- EDIT -- IS A CORS ISSUE
In django settings.py file :
CORS_ORIGIN_WHITELIST = (
'localhost:8000',
'127.0.0.1:4200'
)
INSTALLED_APPS = (
...
'corsheaders',
...
)
MIDDLEWARE = [ # Or MIDDLEWARE_CLASSES on Django < 1.10
...
'corsheaders.middleware.CorsMiddleware',
'django.middleware.common.CommonMiddleware',
...
]
But i don't know if there's a way to set-up CORS settings in Angular
Based on feedback, this is a CORS issue. Your Django server is getting the requests and responding because localhost is an implicitly trusted domain in Django's dev environment, but it isn't configured properly to set the cross origin header, so the browser is not allowing your app to see the response because the server hasn't authorized the domain explicitly.
The problem here is that you've set CORS white list like this:
CORS_ORIGIN_WHITELIST = ( 'localhost:8000', '127.0.0.1:4200' )
it needs to be like this:
CORS_ORIGIN_WHITELIST = ( 'localhost:4200' )
angular runs on localhost, not 127.0.0.1, even though that's what localhost is an alias for, your browser still differentiates them for CORS. Also, you do not need to whitelist the domain your serving off of, that's not crossing any origin as it's the same origin.
In your screenshot, it looks like the response is type "document..." something. The simplest fix, with only the code here, is to convert the string to JSON.
JSON.parse(films)
This is the wrong answer, because it's being set to that because of the CORS issue in the other answers.
We have urls in our Django (Rest Framework) applications like:
r'^endpoint/(?P<item>[a-z_-]+)/$'
r'^endpoint/(?P<item>[a-z_-]+)/(?P<version>[0-9]+(\.[0-9])?)/$'
Both have POST methods available.
We've been using Swagger for a while to document our API but wanted to look at the coreapi documentation included in Django Rest Framework.
Going through our documentation based on the above structure the coreapi action results in:
# Initialize a client & load the schema document
client = coreapi.Client()
schema = client.get("http://localhost:8081/docs/")
# Interact with the first url
action = ["app", "endpoint > create"]
# Interact with the second url
action = ["app", "endpoint > create_0"]
I can understand where create_0 is coming from, but ideally it would add the keyword name as a suffix instead, e.g. create_version.
Is this possible?
Having two keywords right after each other seems to be the problem.
r'^endpoint/(?P<item>[a-z_-]+)/$'
r'^endpoint/(?P<item>[a-z_-]+)/(?P<version>[0-9]+(\.[0-9])?)/$'
Should be replaced with:
r'^endpoint/(?P<item>[a-z_-]+)/$'
r'^endpoint/(?P<item>[a-z_-]+)/version/(?P<version>[0-9]+(\.[0-9])?)/$'
That will give you:
action = ["endpoint", "item > version > create"]
Which looks much cleaner.
This is my first post, and I have a problem I could not make it work django OMAB socialauth of three things I just need to google, facebook, and twitter, google works well with open id, but not much twitter and I put in my
settings. py:
TWITTER_CONSUMER_KEY = '00' this is no real
TWITTER_CONSUMER_SECRET = '00' this is no real
FACEBOOK_APP_ID = '' ihave no key
FACEBOOK_API_SECRET = ''
LINKEDIN_CONSUMER_KEY = ''
LINKEDIN_CONSUMER_SECRET = ''
ORKUT_CONSUMER_KEY = ''
ORKUT_CONSUMER_SECRET = ''ihave no key
GOOGLE_OAUTH2_CLIENT_ID = ''
GOOGLE_OAUTH2_CLIENT_SECRET = ''
SOCIAL_AUTH_CREATE_USERS = True
SOCIAL_AUTH_FORCE_RANDOM_USERNAME = False
SOCIAL_AUTH_DEFAULT_USERNAME = 'socialauth_user'
SOCIAL_AUTH_COMPLETE_URL_NAME = 'socialauth_complete'
LOGIN_ERROR_URL = '/login/error/'
#SOCIAL_AUTH_USER_MODEL = 'app.CustomUser'
SOCIAL_AUTH_ERROR_KEY = 'socialauth_error'
GITHUB_APP_ID = ''
GITHUB_API_SECRET = ''
FOURSQUARE_CONSUMER_KEY = ''
FOURSQUARE_CONSUMER_SECRET = ''
LOGIN_URL = '/login-form/'
LOGIN_REDIRECT_URL = '/'
LOGIN_ERROR_URL = '/login-error/'
I am using the example that comes in the zip of OMAB socialauth django , but not working.
When I created my twitter app, I wrote my domain www.sisvei.com , I am testing locally socialauth django ie 127.0.0.1:8000, then sign in with twitter sends me to this url:
http://127.0.0.1:8000/login/error/ and a message saying is the Incorrect authentication service
this happens with facebook and google oauth and oauth2
I'm new to django and I this much work comprising this part of django socialath hopefully help me, thank you very much.
You need to be more specific on "why it doesn't work". Where are you getting the errors?
When debugging a third-party oauth/openid app in Django, generally it boils down to:
configuration & keys - did you make sure to obtain all of the necessary API keys for the services you will be using, and to add them to your configuration?
urls - did you remember to add the necessary urlpatterns to your base urls.py file?
authentication setup on the server - often, you'll need to have a file available or respond with a specific header when the authentication service hits your server. Have you checked to make sure that is set up?
databases - have you run syncdb after installing the app? Are all the tables set up?
templates - if the third party app requires you to set up templates, do you have them set up?
custom views - are you using custom views? If so, try using the built-in views that came with the third party app first, to see if they work
After those are confirmed, you're going to want to be able to see what requests are taking place. Use the debugger included in Chrome/Safari, or get the web developer add-on for Firefox, and look at the network requests as they happen. Do you see HTTP responses other than 200 (say, 404, 500, 403, etc?) those mean that the services aren't responding correctly.
From your error, it looks like you have not correctly set up your callback URL on Twitter. It should be sending you to www.sisvei.com, not 127.0.0.1. Alternatively, check the URL when you get to the Twitter login page -- is the callback URL in the URL, and is it pointing to 127.0.0.1? Then Django is sending it the wrong callback URL.
Finally this:
I wrote my domain www.sisvei.com python does not support this
Is unclear. As far as I know, Python doesn't care what the domain is.
WAIT A MINUTE ...
Are you using runserver? Are you getting the following error?
Error: "www.sisvei.com" is not a valid port number or address:port pair.
If so, there is an easy fix! Just run it like so:
python manage.py runserver www.sisvei.com:80
That should resolve your error if that's what's happening. You're probably running it as
python manage.py runserver 127.0.0.1
127.0.0.1 is a reserved IP address that points back to localhost, your own computer. As a result, it is not possible to use it for authentication or any other purpose outside of programs running on your own machine. See this article for more info.
I'm not sure, but I might be having similar problems, oscar. For me, SocialAuth was generating an AuthenticationURL for facebook, foursquare and hotmail, but not for google, twitter or any of the other address it supports. I think it may be something wrong with the API, so I posted an issue on the social-auth google group...you may want to check there to see if anyone updates!!
https://code.google.com/p/socialauth/issues/detail?id=282&colspec=ID%20Type%20Status%20Priority%20Milestone%20Owner%20Summary%20Modified
I'm running a django installation on lighttpd +FCGI.
Everything works fine except the admin.
It seems that the redirects after I post something (i.e. I modify sor create an instance of a model) go wrong.
The admin keeps redirecting me to www.xyz.com/django.fcgi/admin/... while django.fcgi should be used only by the lighttp rewrite rule to invoke FCGI.
Here's the redirection in the conf file
url.rewrite-once = (
"^(/media.*)$" => "$1",
"^/favicon\.ico$" => "/media/favicon.ico",
"^(/.*)$" => "/django.fcgi$1",
)
how can I fix this?
The admin site is trying to work out the URL to use based on the SCRIPT_NAME variable passed by lighttpd, but that's the rewritten URL, not the original one. You can force Django to use the original path by adding the following to your settings.py file.
FORCE_SCRIPT_NAME = ""
See the FORCE_SCRIPT_NAME documentation and the Django FastCGI docs for more information.