Using https as standard with django project - python

I am learning django and trying to complete my first webapp.
I am using shopify api & boilder plate (starter code) and am having an issue with the final step of auth.
Specifically, the redirect URL -- it's using HTTP:// when it should NOT and I don't know how to change it..
#in my view
def authenticate(request):
shop = request.GET.get('shop')
print('shop:', shop)
if shop:
scope = settings.SHOPIFY_API_SCOPE
redirect_uri = request.build_absolute_uri(reverse('shopify_app_finalize')) #try this with new store url?
print('redirect url', redirect_uri) # this equals http://myherokuapp.com/login/finalize/
permission_url = shopify.Session(shop.strip()).create_permission_url(scope, redirect_uri)
return redirect(permission_url)
return redirect(_return_address(request))
Which is a problem because my app uses the Embedded Shopify SDK which causes this error to occur at the point of this request
Refused to frame 'http://my.herokuapp.com/' because it violates the following Content Security Policy directive: "child-src 'self' https://* shopify-pos://*". Note that 'frame-src' was not explicitly set, so 'child-src' is used as a fallback.
How do i change the URL to use HTTPS?
Thank you so much in advance. Please let me know if I can share any other details but my code is practically identical to that starter code

This is what the Django doc says about build_absolute_uri:
Mixing HTTP and HTTPS on the same site is discouraged, therefore
build_absolute_uri() will always generate an absolute URI with the
same scheme the current request has. If you need to redirect users to
HTTPS, it’s best to let your Web server redirect all HTTP traffic to
HTTPS.
So you can do two things:
Make sure your site runs entirely on HTTPS (preferred option): Setup your web server to use HTTPS, see the Heroku documentation on how to do this. Django will automatically use HTTPS for request.build_absolute_uri if the incoming request is on HTTPS.
I'm not sure what gets passed in the shop parameter but if it contains personal data I'd suggest to use HTTPS anyway.
Create the URL yourself:
url = "https://{host}{path}".format(
host = request.get_host(),
path = reverse('shopify_app_finalize'))
But you will still need to configure your server to accept incoming HTTPS requests.

Related

How to obtain the caller's IP address in Flask/Connexion?

I'm using an OpenAPI 3.0 specification (swagger.yml) and use Swagger Codegen to create the corresponding Python Flask application stubs. This is how I run the application to expose my Swagger API:
app = connexion.App(__name__, specification_dir='./swagger/')
app.app.json_encoder = encoder.JSONEncoder
app.add_api('swagger.yaml', arguments={'title': 'My Test API'})
# add CORS support to send Access-Control-Allow-Origin header
CORS(app.app)
So far so good. The application logic is handled within the generated Python stubs which are linked by the x-openapi-router-controller: swagger_server.controllers.user_controller.
I now however need to access HTTP Request specific information within the application itself to for example react differently based on the HTTP_CLIENT_IP address
How can I obtain that information within my controller endpoint?
Use Flask's request context.
For example, to get the HTTP_CLIENT_IP, use:
from flask import request
http_client_ip = request.remote_addr
You can read more about request here.
Attached two related links addressing the same issue on request header parameters and how connexion does not forward them to custom controllers. I ended up manually accessing them via
access_token = connexion.request.headers['access_token']

Get the URL of a server

I am using flask and flask email for sending an email. When I work on I used the localhost as a base url. I deployed it on the server and email sent is still showing with localhost address.
For example
base_url = "http://localhost:0.0.0.6465"
url=base_url+'/login'
I sent an email(i am using flask-mail) with the url and I can login with the url.
With the same script when I deployed on the server I am getting with same localhost address.I need the server URL should be the base url.
To debug this I tried
url=request.base_url+'/login'
I am getting 404 error in the browser if I use this. I dont want to change the initializtion of base_url because I have to use both in the local as well as in the server.
How can I do that?
You can get the URL to the currently running app through request.host_url. But what you really want to to do to get an external URL to a specific part of your application, is to use url_for as you'd do when referencing your regular endpoints, but with the parameter _external=True:
Given that you have:
#app.route('/login')
def login():
....
You can generate an external URL by using:
from flask import (
url_for,
)
...
url = url_for('login', _external=True)
This will also take into account any proxies in front of your application if you need that, as long as you've used the ProxyFix middleware when setting up your app object.
Since this uses the same mechanism as Flask uses when generating URLs between different pages, it should behave just as you want - i.e. it'll work both on localhost and on the remote host.

Redirect uri error when aunthenticating with VK.com

I am trying to develop login with vk.com feature for our website. And testing it locally. In app I have given
http://127.0.0.1/
as base domain. In website during authorization it is requesting url:
https://oauth.vk.com/authorize?client_id=XXXX&redirect_uri=http://127.0.0.1/vk/login/check/&state=trackid=XXXX..
In callback url, I am calling
https://oauth.vk.com/access_token?client_id=XXXX&client_secret=YYYY&redirect_uri=redirect_uri=http://127.0.0.1/vk/login/check/aaa/bbbb&code=
But its not loading VK website for logging in. It shows error
{"error":"invalid_request","error_description":"redirect_uri has wrong
domain, check application settings"}.
Dont know whats wrong. Any help?
Earlier when testing to request code and accesstoken manually, I had given domain in app as https://www.example.com and used https://www.example.com as redirect url when requesting code and access token. At that time it had worked.
Now how can I test it when our website is running locally? Please help
You should open your 8000 port and put to "redirect_uri" your ip. But it's not exactly work, because u should have your own host
go to your app setting in VK set your redirect-uri http://127.0.0.1:5000/anything (port is important/use Port that you are using according to server hosting service). then try it.

Authenticating connection in PySolr

This is the first time I am using Python and Solr. I have my Solr instance set up within tomcat on GCE. I am trying to connect to it from my Python code using PySolr. However, I am not sure how to send authentication parameters via PySolr.
This is the exception I get:
solr = pysolr.Solr('http://MY INSTANCE IP/solr/News', timeout=10)
Apache Tomcat/7.0.28 - Error report HTTP Status 401 - type Status reportmessage description This request requires HTTP authentication ().Apache Tomcat/7.0.28
Please advise.
solr = pysolr.Solr('http://user:pass#IP:8983/solr/')
That's all you need ...
You can pass Solr authentication as part of the Solr connection parameter.
You don't have proper documentation in pySolr on how to carry out authentication. Since pySolr internally uses requests for authentication you can follow authentication in requests.
Here is a small example on custom authentication as well.
In the case of Basic Authentication, you can use it as
solr = pysolr.Solr('http://IP:8983/solr/collection',auth=('username','password'))
or
from requests.auth import HTTPBasicAuth
solr = pysolr.Solr('http://IP:8983/solr/collection',auth=HTTPBasicAuth('username','password'))
This is the proper way of authentication. Passing username and password as a part of URL is not recommended as it might create issues if # or ' are used in any of those may create issues in the authentication.Refer this GitHub issue

Empty reply from Django web service

I have created a web service in django and its hosted on a shared server.The django web service respond to request from a game made in unity. But whenever game tries to request a django Web service url the server send empty resonse.Response is always:
WWW Error: server return empty string
The Unity webplayer expects a http served policy file named "crossdomain.xml" to be available on the domain you want to access with the WWW class, (although this is not needed if it is the same domain that is hosting the unity3d file).So I placed a file "crossdomain.xml" at the root of my domain ,but still i am getting same empty reply.Help plz...
EDIT:
I tried it through browser my service works fine and reply with proper response.And you know what My game can communicate to django web service when both are running on local machine.But now the django project is hosted on actual server and when game tried accessing service it never get response :(
url.py
urlpatterns = patterns('',
url(r'^crossdomain.xml$',views.CrossDomain),
url(r'^ReadFile/$',views.ReadFile),
)
views.py
def CrossDomain(request):
f = open(settings.MEDIA_ROOT+'jsondata/crossdomain.xml', 'r')
data = f.read()
f.close()
return HttpResponse(data, mimetype="application/xml")
def ReadFile(request):
f = open(settings.MEDIA_ROOT+'jsondata/some_file.json', 'r')
data = f.read()
f.close()
return HttpResponse(data, mimetype="application/javascript")
def Test(request):
return HttpResponse("Hello", mimetype="text/plain")
As I said using django for this is slight overkill because you could just serve them. Point aside though. If your serving on a different server it could be
A) Connection problems mean that your response is lost
B) Firewall issues mean that the request mean something
C) The server isn't setup correctly and therefore it justs get an error.
You need to test the response on the server. so is you access the page on the server through your browser. If so then make the game make a request and check the server error and access logs. In the apache access log you should see something like
GET "/url" 200 each time a request is made.
If you don't see any request getting through then either the request isn't made or its been lost.
If you do then the problem is in the code somewhere.

Categories