Flask-Login, Session Management and AJAX

痞子三分冷 提交于 2021-02-20 00:13:10

问题


I'm having trouble getting an AJAX call to work with the Flask-Login current_user object and the @login_required decorator. I believe it has something to do with the session not being passed.

The goal is for a user to click on a link that makes an AJAX call to a route URL that will provide a SSO session ID through a SOAP service. The SOAP service requires an emp_id to be passed which can be accessed through the current_user.emp_id attribute.

I initially attempted the AJAX call without the @login_required decorator and just passing a simple message as such which returned successfully:

app.js

const ssoLinks = document.querySelectorAll('.sso');

ssoLinks.forEach((ssoLink) => {
  ssoLink.addEventListener('click', (e) => generateSSOLink(e, ssoLink.id));
});


function generateSSOLink(e, page) {
  e.preventDefault();

  fetch("/get_bpm_sso_link")
    .then(response => response.json())
    .then(data => console.log(data))
}

views.py

@app.route('/get_bpm_sso_link')
def get_bpm_sso_link():
    data = {
        'msg': 'success'
    }

    print('*'*75)
    print('SUCCESS')
    print('*'*75)

    return jsonify(data)

My next attempt was to access the emp_id in current_user:

views.py

@app.route('/get_bpm_sso_link')
def get_bpm_sso_link():
    data = {
        'msg': 'success'
    }

    print('*'*75)
    print(current_user.emp_id)
    print('*'*75)

    return jsonify(data)

Which gave me this error:

AttributeError: 'AnonymousUserMixin' object has no attribute 'emp_id'

Okay, so then I decided to try and access the same emp_id attribute on the initial index page(where the AJAX lives as well) and was able to do so. It sounds like during an AJAX request, the Flask-Login LoginManager doesn't recognize the session of the current_user. To further this claim, I added the @login_required decorator to the route and the JSON response returned a redirect to the login page.

What can I do to have Flask-Login recognize a user during an AJAX call? If not, what other libraries can handle user session management and AJAX requests seamlessly?


回答1:


So I did some digging this week at Pycon 2018 in Cleveland and came across a noteworthy topic regarding the Fetch API. Seems by default that the API doesn't send any user credentials. To remedy this, it all came down to setting an option within the API:

app.js

function generateSSOLink(e, page) {
  e.preventDefault();

  fetch("/get_bpm_sso_link", {
    credentials: 'include'
  })
    .then(response => response.json())
    .then(data => console.log(data))
}

Now my AJAX request hits my view even with the @login_required decorator.




回答2:


What you need is to login using request loader as per this example on flask for each request

And probably disable setting the Flask Session cookie

Then Using fetch add headers with basic authentication

    fetch('/get_bpm_sso_link', { 
    method: 'get', 
    //or whichever method you are using
    headers: new Headers({
     'Authorization': 'Basic '+btoa('username:password') 
     //btoa base64 encodes your credentials, the flask example above shows how to decode
     })
 });

Ideally because the credentials are not hashed, they should be passed over https in production



来源:https://stackoverflow.com/questions/50236564/flask-login-session-management-and-ajax

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!