Closed jforjay1 closed 3 years ago
@jforjay1 you need to pass Bearer Auth (token) in the header and plus have you got the api key?
@jforjay1 you need to pass Bearer Auth (token) in the header and plus have you got the api key?
@gautam404 I have got the token after confirming the OTP. I have 2 questions.
Thank you
@jforjay1 you need to pass Bearer Auth (token) in the header and plus have you got the api key?
How to get API key?
@deepakezetap public key is available on website. if you want private key you need to register for that. public key is 3sjOr2rmM52GzhpMHjDEE1kpQeRxwFDr4YcBEimi
@gautam404 I also wanted to know and of 2nd question😂 and how to use API key?
3sjOr2rmM52GzhpMHjDEE1kpQeRxwFDr4YcBEimi
Isn't this the public key for the test server? how do we register to get the key for prod server?
@deepakezetap I guess thats the problem!
@patelhir You have be organization/company to get 'x-api-key' for production server and they do not give it to individual.
Check this out might help you to test but wont give exactly what you want https://github.com/cowinapi/developer.cowin/issues/282#issue-895214687
@jforjay1 Do you have any link to get the prod keys? I will register it through the company.
@deepakezetap I guess thats the problem!
@patelhir You have be organization/company to get 'x-api-key' for production server and they do not give it to individual.
Check this out might help you to test but wont give exactly what you want #282 (comment)
But many people says that you don't need API-key a token is enough to get access protected endpoints?
But many people says that you don't need API-key a token is enough to get access protected endpoints?
I am not sure about this. I tried to fetch the beneficiary list using the token through protected api, but got unauthenticated access.
Here is my header:
Authorization=
@deepakezetap check https://github.com/cowinapi/developer.cowin/issues/282#issue-895214687 for authorization
You need to login in basically to generate a token. and login is done by Generating OTP. Check process to generate OTP at https://apisetu.gov.in/public/marketplace/api/cowin#/User%20Authentication%20APIs/generateOTP and also need to confirm it https://apisetu.gov.in/public/marketplace/api/cowin#/User%20Authentication%20APIs/confirmOTP now your token is decrypted.
another problem is after 15 min you need to login again as the session expires.
I have generated token and I get unauthenticated access even if I try with token immediately. Here is my python code:
`import requests import json
user_agent_desktop = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) ' \ 'AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.149 ' \ 'Safari/537.36'
url = "https://cdn-api.co-vin.in/api/v2/appointment/beneficiaries"
headers = { 'authorization': "Bearer {token}", 'Accept-Language': 'hi_IN', 'Content-Type': 'application/json', 'Accept': 'application/json', 'User-Agent': user_agent_desktop }
response = requests.get(url, headers=headers)
print(response.text)`
@patelhir Maybe its because API key we need private x-api-key.
Closing this Issue!
Things noted: If you want to book an appointment on Production server need a private key, that is not available to the general public. However, you can use the public key on Test server to try.
I am not sure about this. I tried to fetch the beneficiary list using the token through protected api, but got unauthenticated access. Here is my header: Authorization= OR Authorization=Bearer I don't know what I am doing wrong here.
@deepakezetap The following [python] code works for me,
URL = "https://cdn-api.co-vin.in/api/v2/appointment/beneficiaries"
response = requests.get(URL, headers={
"accept": "application/json",
"Accept-Language": "en_US",
"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.93 Safari/537.36",
"authorization": "Bearer {}".format(bearer_token)
})
print(response.json())
bearer_token
@kichappa How did you get the bearer_token? Is the same token from OTP confirmation?
Is the same token from OTP confirmation?
Yes.
I am not sure about this. I tried to fetch the beneficiary list using the token through protected api, but got unauthenticated access. Here is my header: Authorization= OR Authorization=Bearer I don't know what I am doing wrong here.
@deepakezetap The following [python] code works for me,
URL = "https://cdn-api.co-vin.in/api/v2/appointment/beneficiaries" response = requests.get(URL, headers={ "accept": "application/json", "Accept-Language": "en_US", "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.93 Safari/537.36", "authorization": "Bearer {}".format(bearer_token) }) print(response.json())
EVen this code gives unauthenticated access.
Even this code gives unauthenticated access.
@patelhir This is the response I got,
{
'beneficiaries': [{
'beneficiary_reference_id': 'REDACTED',
'name': 'REDACTED',
'birth_year': 'REDACTED',
'gender': 'REDACTED',
'mobile_number': 'REDACTED',
'photo_id_type': 1,
'photo_id_number': 'REDACTED',
'comorbidity_ind': 'N',
'vaccination_status': 'Partially Vaccinated',
'vaccine': 'COVISHIELD',
'dose1_date': 'REDACTED',
'dose2_date': '',
'appointments': []
}, {
'beneficiary_reference_id': 'REDACTED',
'name': 'REDACTED',
'birth_year': 'REDACTED',
'gender': 'REDACTED',
'mobile_number': 'REDACTED',
'photo_id_type': 1,
'photo_id_number': 'REDACTED',
'comorbidity_ind': '',
'vaccination_status': 'Partially Vaccinated',
'vaccine': 'COVISHIELD',
'dose1_date': 'REDACTED',
'dose2_date': '',
'appointments': []
}, {
'beneficiary_reference_id': 'REDACTED',
'name': 'REDACTED',
'birth_year': 'REDACTED',
'gender': 'Male',
'mobile_number': 'REDACTED',
'photo_id_type': 'Aadhaar Card',
'photo_id_number': 'REDACTED',
'comorbidity_ind': 'N',
'vaccination_status': 'Not Vaccinated',
'vaccine': '',
'dose1_date': '',
'dose2_date': '',
'appointments': []
}]
}
Without passing API key? Can you send your whole python script?
@patelhir Sure. Forgive me for any redundancy in the code.
First, I generateOTP
and validateOTP
.
import requests, hashlib, pathlib
# just some random token
secret="U2FsdGVkX1+TPSV7/E3PENx8ObiaQ9mIov/NO0Ry1mt5O8Awl1Ix+kX68wcBDbBTODj4Ejy3KkeW3n8ZqYhlqA=="
URL = "https://cdn-api.co-vin.in/api/v2/auth/generateMobileOTP"
response = requests.post(URL, json={
"mobile": "9876543210",
"secret": secret
}, headers={
"accept": "application/json",
"Accept-Language": "en_US",
"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.93 Safari/537.36",
})
otp=str(input("Enter OTP: "))
otpHash=hashlib.sha256(otp.encode()).hexdigest()
URL = "https://cdn-api.co-vin.in/api/v2/auth/validateMobileOtp"
response = requests.post(URL, json={
"otp": otpHash,
"txnId": response.json()['txnId']
}, headers={
"accept": "application/json",
"Accept-Language": "en_US",
"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.93 Safari/537.36",
})
# the response has the bearer token
bearer_token=response.json()['token']
Now, I access the list of beneficiaries as so.
URL = "https://cdn-api.co-vin.in/api/v2/appointment/beneficiaries"
response = requests.get(URL, headers={
"accept": "application/json",
"Accept-Language": "en_US",
"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.93 Safari/537.36",
"authorization": "Bearer {}".format(bearer_token)
})
# printing the beneficiaries list
print(response.json())
Suppose I want the vaccination certificate,
URL = "https://cdn-api.co-vin.in/api/v2/registration/certificate/download?beneficiary_reference_id={}".format(response.json()['beneficiaries'][0]['beneficiary_reference_id'])
response = requests.get(URL, headers={
"accept": "application/json",
"Accept-Language": "en_US",
"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.93 Safari/537.36",
"authorization": "Bearer {}".format(bearer_token)
})
with pathlib.Path("certificate.pdf") as f:
f.write_bytes(response.content)
Hope this helps!
@kichappa Can You guide us how you got the token no
@gautam404 As I said in #273, it is just a token that the CoWin - Self Registration Portal generated when I tried to authenticate using OTP.
@patelhir Sure. Forgive me for any redundancy in the code.
First, I
generateOTP
andvalidateOTP
.import requests, hashlib, pathlib # just some random token token="U2FsdGVkX1+TPSV7/E3PENx8ObiaQ9mIov/NO0Ry1mt5O8Awl1Ix+kX68wcBDbBTODj4Ejy3KkeW3n8ZqYhlqA==" URL = "https://cdn-api.co-vin.in/api/v2/auth/generateMobileOTP" response = requests.post(URL, json={ "mobile": "9876543210", "secret": token }, headers={ "accept": "application/json", "Accept-Language": "en_US", "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.93 Safari/537.36", }) otp=str(input("Enter OTP: ")) otpHash=hashlib.sha256(otp.encode()).hexdigest() URL = "https://cdn-api.co-vin.in/api/v2/auth/validateMobileOtp" response = requests.post(URL, json={ "otp": otpHash, "txnId": response.json()['txnId'] }, headers={ "accept": "application/json", "Accept-Language": "en_US", "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.93 Safari/537.36", }) # the response has the bearer token bearer_token=response.json()['token']
Now, I access the list of beneficiaries as so.
URL = "https://cdn-api.co-vin.in/api/v2/appointment/beneficiaries" response = requests.get(URL, headers={ "accept": "application/json", "Accept-Language": "en_US", "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.93 Safari/537.36", "authorization": "Bearer {}".format(bearer_token) }) # printing the beneficiaries list print(response.json())
Suppose I want the vaccination certificate,
URL = "https://cdn-api.co-vin.in/api/v2/registration/certificate/download?beneficiary_reference_id={}".format(response.json()['beneficiaries'][0]['beneficiary_reference_id']) response = requests.get(URL, headers={ "accept": "application/json", "Accept-Language": "en_US", "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.93 Safari/537.36", "authorization": "Bearer {}".format(bearer_token) }) with pathlib.Path("certificate.pdf") as f: f.write_bytes(response.content)
Hope this helps!
That works, thank you so much, I was getting error from long.
@patelhir Happy to help!
@kichappa - The token generated is using a AES encryption of a guid and a key both of them seemed to be hardcoded in the .js fil. The guid may denote the version of the application. Need to check if this is changing for every release. For me it was "b5cab167-7977-4df1-8027-a63aa144f04e". This GUID is also getting stored in the jwt token under "secret_key"
@rvramesh oh okay. Also, I noticed that this secret-key
changes for each generateOTP
on the portal. Thank you for pointing out that the JWT token stores it too.
Also, do you have an idea of how one can an acceptable secret-key
?
@kichappa open developer tools and search for the guid i gave. In login module, the secret
is set. If you notice it performs AES encryption on the guid and key (both are hardcoded and is not changing). But AES encryption has a mechanism https://stackoverflow.com/a/31836718/30594 where output is different every time when the same text is encrypted.
This explains why you could still use the old secret repeatedly.
@rvramesh This is what I see in their js
file.
key: "anonymousLogin",
value: function () {
return this.http.post(i.a.auth_prefix_url + "/guest/login", {
user_name: "b5cab167-7977-4df1-8027-a63aa144f04e"
}, {
responseType: "text"
}).pipe(Object(r.a)((function (e) {
return e
})))
}
I don't see how/where they are encrypting this. (This is on line 18390 after beautifying the code).
@kichappa - Search for the one more occurrence of that guid or for the keyword secret
@rvramesh thanks for your input. It works.
thanks for your input. It works.
were u talking about having a permanent decrypted token from the otp if yes how?
@kichappa - The token generated is using a AES encryption of a guid and a key both of them seemed to be hardcoded in the .js fil. The guid may denote the version of the application. Need to check if this is changing for every release. For me it was "b5cab167-7977-4df1-8027-a63aa144f04e". This GUID is also getting stored in the jwt token under "secret_key"
in which file
Were you talking about having a permanent decrypted token from an OTP?
@arnav7633 No. That was about the secret
that is sent in a generateMobileOTP
method.
In which file?
The client sided js
script that works when the CoWin portal is loaded.
@patelhir Sure. Forgive me for any redundancy in the code.
First, I
generateOTP
andvalidateOTP
.import requests, hashlib, pathlib # just some random token token="U2FsdGVkX1+TPSV7/E3PENx8ObiaQ9mIov/NO0Ry1mt5O8Awl1Ix+kX68wcBDbBTODj4Ejy3KkeW3n8ZqYhlqA==" URL = "https://cdn-api.co-vin.in/api/v2/auth/generateMobileOTP" response = requests.post(URL, json={ "mobile": "9876543210", "secret": token }, headers={ "accept": "application/json", "Accept-Language": "en_US", "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.93 Safari/537.36", }) otp=str(input("Enter OTP: ")) otpHash=hashlib.sha256(otp.encode()).hexdigest() URL = "https://cdn-api.co-vin.in/api/v2/auth/validateMobileOtp" response = requests.post(URL, json={ "otp": otpHash, "txnId": response.json()['txnId'] }, headers={ "accept": "application/json", "Accept-Language": "en_US", "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.93 Safari/537.36", }) # the response has the bearer token bearer_token=response.json()['token']
Now, I access the list of beneficiaries as so.
URL = "https://cdn-api.co-vin.in/api/v2/appointment/beneficiaries" response = requests.get(URL, headers={ "accept": "application/json", "Accept-Language": "en_US", "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.93 Safari/537.36", "authorization": "Bearer {}".format(bearer_token) }) # printing the beneficiaries list print(response.json())
Suppose I want the vaccination certificate,
URL = "https://cdn-api.co-vin.in/api/v2/registration/certificate/download?beneficiary_reference_id={}".format(response.json()['beneficiaries'][0]['beneficiary_reference_id']) response = requests.get(URL, headers={ "accept": "application/json", "Accept-Language": "en_US", "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.93 Safari/537.36", "authorization": "Bearer {}".format(bearer_token) }) with pathlib.Path("certificate.pdf") as f: f.write_bytes(response.content)
Hope this helps!
@kichappa 1) do I have to replace "mobile" with my mobile number? 2) For generating the token for the very first time do I have to use the demo API keys i.e. "3sjOr2.............." 3) How long the same token lasts?
@CodeWithBishal
Do I have to replace "mobile" with my mobile number?
Yes. Replace the 9876543210
with your mobile number.
2) For generating the token for the very first time, do I have to use the demo API keys i.e. "3sjOr2.............."?
I'm not sure what you're talking about.
3) How long the same token lasts?
A bearer token lasts 3 minutes.
Were you talking about having a permanent decrypted token from an OTP?
@arnav7633 No. That was about the
secret
that is sent in agenerateMobileOTP
method.In which file?
The client sided
js
script that works when the CoWin portal is loaded.
is the 'secret' and the guid responsible for making a token? if yes how can i get this secret cuz in my main it was named 'client_secret'
@kichappa "I'm not sure what you're talking about."
In your code there is a secret/token how do I generate this? (just some random token secret="U2FsdGVkX1+TPSV7/E3PENx8ObiaQ9mIov/NO0Ry1mt5O8Awl1Ix+kX68wcBDbBTODj4Ejy3KkeW3n8ZqYhlqA==")
@kichappa "I'm not sure what you're talking about."
In your code there is a secret/token how do I generate this? (just some random token secret="U2FsdGVkX1+TPSV7/E3PENx8ObiaQ9mIov/NO0Ry1mt5O8Awl1Ix+kX68wcBDbBTODj4Ejy3KkeW3n8ZqYhlqA==")
thats the bearer received after confirming the otp i suppose
@CodeWithBishal it is just a secret that you send to authenticate that you "are the CoWin Portal". You can use the same token I've given here.
You may check out #273 or the api.py
file in my repo for more information.
@arnav7633 it's not the bearer token.
@kichappa
I am getting 504 on https://cdn-api.co-vin.in/api/v2/auth/validateMobileOtp
in the code you shared. Is it working fine for you?
@vishal24tuniki try adding these to your request header.
"origin": "https://selfregistration.cowin.gov.in",
"referer": "https://selfregistration.cowin.gov.in/"
Thanks @kichappa Working now!
Not able to book appoinment using url "https://cdn-api.co-vin.in/api/v2/appointment/schedule". Response returns 401. Below is the code: (Consider session_list is declared above and has correct value)
Please help me solve this and let me know what I am doing wrong?