linkedin-api
linkedin-api copied to clipboard
Logout functionality
Adding a logout functionality would allow accounts rotation and prevent them from being banned in case their programs requires nested requests
Logout seems to be a simple GET request to the below endpoint
https://www.linkedin.com/voyager/api/takeovers?q=takeoverFlow&takeoverFlow=SIGN_OUT
Hi @abinpaul1 , I am willing to implement the changes but the network tab is not helping me to get the logout endpoint and request
I looked at it again and I think we have to make 2 requests to successfully logout. The first one is to the above endpoint and once that returns 200 OK. We need to make another one to https://www.linkedin.com/uas/logout?csrfToken=ajax%3A1661371993889639161
where the CSRF token is the JSESSIONID from cookie. I believe this will return a 303
response. After both these requests it seems logout is successfull.
@engahmed1190 Would you like to try these out and confirm?
@abinpaul1
I have tried it, it returns the login page of Linkedin in HTML Format but the session is active
First I used takeovers
then logout
Sorry for the late reply. I tried looking at the flow again. It seems there is another endpoint in between as well
GET /checkpoint/rm/validate
. Note this is not part of voyager api
So the entire logout flow goes like :
GET https://www.linkedin.com/voyager/api/takeovers?q=takeoverFlow&takeoverFlow=SIGN_OUT
GET https://www.linkedin.com/checkpoint/rm/validate
GET https://www.linkedin.com/uas/logout?csrfToken=ajax%3A1661371993889639161
All these 3 endpoints have to be hit in order to get the session terminated.
Thanks @abinpaul1 for your reply the new route returns : {"memberEligible":true}
but the session is still active .
I will add my code here for reference maybe something is missing
def logout(self):
"""Logs out of the current session"""
url_params = {
"q": "takeoverFlow",
"takeoverFlow": "SIGN_OUT",
}
url = f"/takeovers"
res = self._fetch(url, params=url_params)
data = res.json()
if data and "status" in data and data["status"] != 200:
self.logger.info("request failed: {}".format(data["status"]))
return {}
if data and res.status_code == 200:
cookies_dict = self.client.session.cookies.get_dict()
JSESSIONID = cookies_dict["JSESSIONID"]
validate_url = f"/checkpoint/rm/validate"
validate_response = self._fetch(validate_url,base_request=True,params={})
self.logger.info("validation {}".format(validate_response.json()))
url = f"/uas/logout"
logout_params = {"csrfToken":JSESSIONID}
logout_response = self._fetch(url,base_request=True,params=logout_params)
self.logger.info(" logout status code {}".format(logout_response.status_code))
return logout_response.status_code == 303
else:
return data
I looked into this some more.
- Now it seems the only request to be made is actually just
GET https://www.linkedin.com/uas/logout?csrfToken=ajax%3A1661371993889639161
. - However the problem seems to be that, in linkedin-api we, authenticate using
/uas/authenticate
endpoint, but when I check it now, Linkedin now uses a different endpoint/uas/login-submit
with a slightly differnet payload as well. I suspect that cookies being set are different for this endpoint and those different cookies are necessary to cause the logout when we hit the/uas/logout
endpoint.
payload = {
"session_key": username,
"session_password": password,
"loginCsrfParam": self.session.cookies["bcookie"].split("&")[1],
}
In order to verify this hypothesis, we will have to change authentication in linkedin-api to use the new endpoint(/uas/login-submit) to successfully authenticate and then try logout. This looks like a lot of changes has to be made to get this to work.
Hi @abinpaul1 .
I have done some investigation, and found a new route https://www.linkedin.com/psettings/sessions/delete
.
It can be used to log-out from a specific session.
Now, I am getting an authorized session, You can find it on the session page try to log-out from one session and see the Network Tab. I think we can replicate this request call, waiting for your input
Cool. That does look like a valid way to logout. But i think it seems to require password as well to do the logout. The ideal solution would be to logout without having to retype the password, but that seems to require a lot of changes. We can definitely try adding this endpoint for now.
I think we would need to investigate how we get the sessionId
. I believe there is an endpoint that returns all the active sessions of a user and we would be able to choose the current sessionId from that. Once we have that we can add the logout
method which uses that endpoint to get current sessionId and password supplied as argument to do the logout.