Forum Settings
Forums

[USER SUBMITTED GUIDE] How to access the new MAL API using OAuth 2.0

New
Reply Disabled for Non-Club Members
Pages (4) « 1 [2] 3 4 »
Aug 23, 2020 8:34 AM
四十二

Offline
Mar 2016
488
Fribbtastic said:
That is actually a good idea to do that with a small website that just retrieves the authorisation code through JavaScript which is also just client-side.

I would have to look into how I can integrate this in the settings page because this is just defined through a formatted text file which is then loaded by Plex to read the settings, but even if that doesn't work this would then just be another step in the "setup" or installation process.

Just remember that the website must be served via HTTPS, or you won't be able to receive the authorisation code. Good luck with the project!
HTCPCP/1.0  ★ MetaMAL  ★ Picture credits: Kieed & 1041uuu
Aug 24, 2020 7:34 AM

Offline
Jun 2014
9
Hey,

When taking out the Client ID I need to specify some URLs and a homepage. The thing is, I want to use the MAL API for discord and I really don't want to set up any servers to have the redirect URLs and the homepage.

Is there any way to bypass these requirements? Or do I still need to set up a server?
Aug 24, 2020 8:25 AM
四十二

Offline
Mar 2016
488
Wh1teD said:
When taking out the Client ID I need to specify some URLs and a homepage. The thing is, I want to use the MAL API for discord and I really don't want to set up any servers to have the redirect URLs and the homepage.

It shouldn't be a problem if you use your MAL profile's URL as your homepage, but the real issue would be the redirect URL. The OAuth protocol requires that somewhere there must be a component able to catch the Authorisation Code so that it can convert it into an Access and Refresh Tokens.

Building a Discord bot implicitly requires an environment where you can keep it running 24/7, so maybe you can add a minimalistic HTTP server which can receive the code.

Alternatively, you can follow an approach similar to the one I described in #49, i.e. redirecting the users to a static web page which simply displays the Authorisation Code so that it can be copy-pasted and sent to your bot to complete the authorisation phase. Full description:


Either way, I understand that the OAuth protocol is not ideal in many situations. Hopefully, the dev team will add a simpler way to authenticate a user in the future. For testing purpose, you can set the redirect URL to http://localhost/oauth or something like it.
HTCPCP/1.0  ★ MetaMAL  ★ Picture credits: Kieed & 1041uuu
Aug 25, 2020 12:22 AM

Offline
Jun 2014
9
ZeroCrystal said:
Wh1teD said:
When taking out the Client ID I need to specify some URLs and a homepage. The thing is, I want to use the MAL API for discord and I really don't want to set up any servers to have the redirect URLs and the homepage.

It shouldn't be a problem if you use your MAL profile's URL as your homepage, but the real issue would be the redirect URL. The OAuth protocol requires that somewhere there must be a component able to catch the Authorisation Code so that it can convert it into an Access and Refresh Tokens.


Building a Discord bot implicitly requires an environment where you can keep it running 24/7, so maybe you can add a minimalistic HTTP server which can receive the code.

Alternatively, you can follow an approach similar to the one I described in #49, i.e. redirecting the users to a static web page which simply displays the Authorisation Code so that it can be copy-pasted and sent to your bot to complete the authorisation phase. Full description:


Either way, I understand that the OAuth protocol is not ideal in many situations. Hopefully, the dev team will add a simpler way to authenticate a user in the future. For testing purpose, you can set the redirect URL to http://localhost/oauth or something like it.


Hey, don't worry about it. I completely understand why all of this necessary :) Thanks for the help, I now know what I need to do, and you are right in that the bot still need to be run on something so doing a minimal "server" for this is not a big deal.
Aug 28, 2020 10:04 PM
Offline
Jun 2020
4
I'm stuck at the beginning of step 4 in your guide trying to get the token. When I go to my URL in the Firefox, I get a 405 Method Not Allowed error. My link is formatted as "https://myanimelist.net/v1/oauth2/token?client_id={client_id}&client_secret={client_secret}&code={code}&code_verifier={code_verifier}&grant_type=authorization_code", which seems to be correct for a web app.
Aug 29, 2020 5:16 AM

Offline
Apr 2010
2844
jacobament said:
I'm stuck at the beginning of step 4 in your guide trying to get the token. When I go to my URL in the Firefox, I get a 405 Method Not Allowed error. My link is formatted as "https://myanimelist.net/v1/oauth2/token?client_id={client_id}&client_secret={client_secret}&code={code}&code_verifier={code_verifier}&grant_type=authorization_code", which seems to be correct for a web app.

This is because you are trying to send a GET request (with all the parameters in the URL), instead of a POST request (with all the parameters in the body of the request), which is what the /token function requires.

It's quite harder to simulate directly a POST request in Firefox (you need to use debugging tools and/or addons), so you may need to use another tool, or code something in the programming language of your choice to do it for you.
Aug 29, 2020 2:48 PM
Offline
Jun 2020
4
Jhiday said:
This is because you are trying to send a GET request (with all the parameters in the URL), instead of a POST request (with all the parameters in the body of the request), which is what the /token function requires.

It's quite harder to simulate directly a POST request in Firefox (you need to use debugging tools and/or addons), so you may need to use another tool, or code something in the programming language of your choice to do it for you.


So I tried it with Python and I just get a 400 error with that, but I don't know what could have done wrong syntactically because it seems straightforward. Here's what I have:

token_url = f'https://myanimelist.net/v1/oauth2/token'
data = {'client_id': client_id,
'client_secret': client_secret,
'code': code,
'code_verifier': code_verifier,
'grant_type': 'authorization_code'}
x = requests.post(url=token_url, data=data)
Aug 29, 2020 4:27 PM

Offline
Apr 2010
2844
jacobament said:
So I tried it with Python and I just get a 400 error with that, but I don't know what could have done wrong syntactically because it seems straightforward.

Most probable answer : you're encoding your POST data wrong.
You shouldn't send an array, but an url-like string :
data = "client_id={client_id}&client_secret={client_secret}&code={code}&code_verifier={code_verifier}&grant_type=authorization_code"
Aug 29, 2020 4:38 PM
四十二

Offline
Mar 2016
488
jacobament said:
So I tried it with Python and I just get a 400 error with that, but I don't know what could have done wrong syntactically because it seems straightforward.

Strange. I ran the following code and it worked swiftly:

Try double-checking that you've inputted the right Client ID/Secret and that you've not accidentally put a whitespace at the start or end of the codes/strings. Plus, keep in mind that the Authorisation Code is short-lived: you must run your code at maximum a few minutes after you've received the code.

Jhiday said:
You shouldn't send an array, but an url-like string :
data = "client_id={client_id}&client_secret={client_secret}&code={code}&code_verifier={code_verifier}&grant_type=authorization_code"

That's not exactly how the Python's requests module works. The curly brackets mark a dictionary/map and not an array as in many C-like languages, they're the right choice in this situation. Any kind of internal encoding is automatically performed by the library, you simply have to prepare a request like the one I've written just now.
ZeroCrystalAug 29, 2020 4:47 PM
HTCPCP/1.0  ★ MetaMAL  ★ Picture credits: Kieed & 1041uuu
Aug 29, 2020 5:05 PM
Offline
Jun 2020
4
ZeroCrystal said:
Strange. I ran the following code and it worked swiftly:

Try double-checking that you've inputted the right Client ID/Secret and that you've not accidentally put a whitespace at the start or end of the codes/strings. Plus, keep in mind that the Authorisation Code is short-lived: you must run your code at maximum a few minutes after you've received the code.


Well, that time limit was definitely one thing I messed up on (I try to avoid dealing with this stuff as much as possible, so I don't have much experience), but it doesn't seem to be the only thing. I got the text return from the post request this time and it is:



I did not change the redirect URL between running generating the authorization code, generated the code seconds beforehand, and I think the "Failed to verify `code_verifier`." must be wrong because I copied what you put in the guide exactly and I was able to get an auth code with it.
Aug 30, 2020 7:00 AM
四十二

Offline
Mar 2016
488
jacobament said:
I got the text return from the post request this time and it is:



I did not change the redirect URL between running generating the authorization code, generated the code seconds beforehand, and I think the "Failed to verify `code_verifier`." must be wrong because I copied what you put in the guide exactly and I was able to get an auth code with it.

As a test, can you try using a static Code Challenge/Verifier like a 128 characters-long string containing the same character? (e.g. 'A' × 128 times, you can copy-paste it from here)
HTCPCP/1.0  ★ MetaMAL  ★ Picture credits: Kieed & 1041uuu
Aug 30, 2020 1:41 PM
Offline
Jun 2020
4
ZeroCrystal said:

As a test, can you try using a static Code Challenge/Verifier like a 128 characters-long string containing the same character? (e.g. 'A' × 128 times, you can copy-paste it from here)

Man, I'm dumb. it was because I kept rerunning the code to generate a new code_verifier in the same script as the post request, so it kept generating a new verifier, hence them not matching. Now I was able to get the response I was expecting. Thank you for the help!
Sep 9, 2020 3:58 PM

Offline
Dec 2019
3531
I did this
https://myanimelist.net/v1/oauth2/authorize?response_type=code&client_id=8ef0267fd86a187d479e6fcd7e1bb42a&code_challenge=AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

then this


But didn't work
Click here to see My Tampermonkey Scripts For MAL

If you like my work, please consider supporting it!
Cryptos / Patreon / Ko-Fi / BuyMeaCoffee https://cyber-sec0.github.io
Sep 10, 2020 5:42 AM
四十二

Offline
Mar 2016
488
hacker09 said:
I did this
https://myanimelist.net/v1/oauth2/authorize?response_type=code&client_id=8ef0267fd86a187d479e6fcd7e1bb42a&code_challenge=AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

then this

The code_verifier parameter of the POST request should be set to AAAAAA... (the same Code Verifier / Code Challenge which you put in the first URL). Change that and the code will work as expected (I've just tested it).

Also, be aware that you only have a few minutes to send the POST request after that you've received an Authorisation Code.
HTCPCP/1.0  ★ MetaMAL  ★ Picture credits: Kieed & 1041uuu
Sep 10, 2020 6:22 AM

Offline
Dec 2019
3531
Thanks, that worked.

Is this request.setRequestHeader("Authorization", "Bearer YOUR_ACCESS_TOKEN"); token permanent and will never change right?

I don't need to run all the js codes you did every single time right? I just need to run them once to generate my own Bearer YOUR_ACCESS_TOKEN, then I add that same and unchangeable token to every api call that the user of my app will do right?
hacker09Sep 10, 2020 6:26 AM
Click here to see My Tampermonkey Scripts For MAL

If you like my work, please consider supporting it!
Cryptos / Patreon / Ko-Fi / BuyMeaCoffee https://cyber-sec0.github.io
Sep 10, 2020 6:30 AM
四十二

Offline
Mar 2016
488
hacker09 said:
Is this request.setRequestHeader("Authorization", "Bearer YOUR_ACCESS_TOKEN"); token permanent and will never change right?

Yep, you need to add it to all API calls.

hacker09 said:
I don't need to run all the js codes you did every single time right? I just need to run them once to generate my own Bearer YOUR_ACCESS_TOKEN, then I add that same and unchangeable token to every api call that the user of my app will do right?

Correct, but remember that an Access Token is valid for around 1 month. Before the expiration date, you have to use the Refresh Token to receive a new Access and Refresh Tokens. This step can be executed automatically with no user interaction.
HTCPCP/1.0  ★ MetaMAL  ★ Picture credits: Kieed & 1041uuu
Sep 10, 2020 6:43 AM

Offline
Dec 2019
3531
Thanks
So basically I will need to make the app run once a month codes similar to

right?

I tried running that codes again but I got the error {"error":"invalid_request","message":"The request is missing a required parameter, includes an invalid parameter value, includes a parameter more than once, or is otherwise malformed.","hint":"Authorization code has expired"}

And I didn't save my Bearer YOUR_ACCESS_TOKEN anywhere
Will I need to exclude my api and make a new one again?
Click here to see My Tampermonkey Scripts For MAL

If you like my work, please consider supporting it!
Cryptos / Patreon / Ko-Fi / BuyMeaCoffee https://cyber-sec0.github.io
Sep 10, 2020 6:48 AM
四十二

Offline
Mar 2016
488
hacker09 said:
So basically I will need to make the app run once a month codes similar to

right?

Yes, the code is very similar. Check the Step 5 of my guide to see the list of parameters.

hacker09 said:
I tried running that codes again but I got the error {"error":"invalid_request","message":"The request is missing a required parameter, includes an invalid parameter value, includes a parameter more than once, or is otherwise malformed.","hint":"Authorization code has expired"}

And I didn't save my Bearer YOUR_ACCESS_TOKEN anywhere
Will I need to exclude my api and make a new one again?

Unfortunately, an Authorisation Code can only be used once. You will need to start again and save the token somewhere.
HTCPCP/1.0  ★ MetaMAL  ★ Picture credits: Kieed & 1041uuu
Sep 10, 2020 7:27 AM

Offline
Dec 2019
3531
So I won't be able to use AAA anymore?
Click here to see My Tampermonkey Scripts For MAL

If you like my work, please consider supporting it!
Cryptos / Patreon / Ko-Fi / BuyMeaCoffee https://cyber-sec0.github.io
Sep 10, 2020 8:12 AM
四十二

Offline
Mar 2016
488
hacker09 said:
So I won't be able to use AAA anymore?

Yes, you can still use it as many times as you want. That's the Code Verifier.

What you cannot use is the old Authorisation Code, the one you've copied from the URL after being redirected from the authorisation dialogue.
HTCPCP/1.0  ★ MetaMAL  ★ Picture credits: Kieed & 1041uuu
Sep 10, 2020 9:08 AM

Offline
Dec 2019
3531
Ok, Got it.
Thank you
Click here to see My Tampermonkey Scripts For MAL

If you like my work, please consider supporting it!
Cryptos / Patreon / Ko-Fi / BuyMeaCoffee https://cyber-sec0.github.io
Nov 2, 2020 9:04 AM
Offline
Mar 2020
5
Hey, while step 4 i will just get
{
"error": "unsupported_grant_type",
"message": "The authorization grant type is not supported by the authorization server.",
"hint": "Check the `grant_type` parameter"
}

my grant_type: authorization_code
Nov 2, 2020 9:15 AM
四十二

Offline
Mar 2016
488
Atronix said:
Hey, while step 4 i will just get
{
"error": "unsupported_grant_type",
"message": "The authorization grant type is not supported by the authorization server.",
"hint": "Check the `grant_type` parameter"
}

The unsupported_grant_type is also used when the POST request's body wasn't properly encoded. It must be a JSON object form URL encoded, but maybe the library you're using encoded it in a different way.

Do you mind posting your code?
ZeroCrystalNov 2, 2020 10:24 AM
HTCPCP/1.0  ★ MetaMAL  ★ Picture credits: Kieed & 1041uuu
Nov 2, 2020 9:42 AM
Offline
Mar 2020
5
I think you don't need my IDs, Tokens and all right?

$postData = array(
'client_id' => $clientID,
'client_secret' => $clientSec,
'code' => $code,
'code_verifier' => $codeVeri,
'grant_type' => "authorization_code"
);

$context = stream_context_create(array(
'http' => array(
'method' => 'POST',
'content' => json_encode($postData)
)
));

$response = file_get_contents('https://myanimelist.net/v1/oauth2/token', FALSE, $context);

(needed to rebuild it after some previous tries so I forgot to add grant type but didn't change when added)
AtronixNov 2, 2020 9:47 AM
Nov 2, 2020 10:22 AM
Offline
Mar 2020
5
$ch = curl_init('https://myanimelist.net/v1/oauth2/token');
curl_setopt_array($ch, array(
CURLOPT_POST => TRUE,
CURLOPT_RETURNTRANSFER => TRUE,
CURLOPT_HTTPHEADER => array('Content-Type: application/json'),
CURLOPT_POSTFIELDS => json_encode($postData)
));

$response = curl_exec($ch);

trying via cURL didn't change anything
Nov 2, 2020 10:23 AM
四十二

Offline
Mar 2016
488
Sorry @Atronix, I've got distracted. I told you that the request should be JSON-encoded, while it must be form URL encoded (as stated in the guide). Either way, wrap your $postData array with http_build_query(...), remove json_encode(...), and the code works.

ZeroCrystalNov 2, 2020 10:26 AM
HTCPCP/1.0  ★ MetaMAL  ★ Picture credits: Kieed & 1041uuu
Nov 2, 2020 10:59 AM
Offline
Mar 2020
5
No problem, it worked perfectly. Thanks, but I didn't understand exactly, am I supposed to always refresh the access token when I want to use the API? Sorry if that's a stupid question I just didn't work with OAuth2 yet
Nov 2, 2020 11:25 AM
四十二

Offline
Mar 2016
488
Atronix said:
Thanks, but I didn't understand exactly, am I supposed to always refresh the access token when I want to use the API? Sorry if that's a stupid question I just didn't work with OAuth2 yet

When you want to use the API you need to have a valid Access Token. The lifetime of an Access Token is expressed by the expires_in parameter and is currently set to 31 days (but it will be reduced in the future to approximately one hour).

This means that you can freely use the API as long as the Access Token you're using is valid. Once expired, your only choice is to obtain a new one using the Refresh Token. The Refresh Token always have a lifetime of 31 days since its issuing. Refreshing a token means that you will get a brand new Access and Refresh Tokens which you will have to use instead of the previous ones.

You can also refresh a token before the expiration of the Access Token. The specific modality depends on the kind of application you're using.
HTCPCP/1.0  ★ MetaMAL  ★ Picture credits: Kieed & 1041uuu
Nov 2, 2020 11:39 AM
Offline
Mar 2020
5
OOH okay, I didn't get the fact I will get a new refresh token as well... if that's the case I just can send a request all thirty days to get a new one and set the new one into my database. I run a website and wanted to display my anime stats on it so I need always a valid access token. The next problem (sorry for annoying you xD) when I get the response of my account there is all the needed information about me, except the anime stats.
Nov 2, 2020 11:54 AM
四十二

Offline
Mar 2016
488
Atronix said:
The next problem (sorry for annoying you xD) when I get the response of my account there is all the needed information about me, except the anime stats.

I suggest you to consult the official API docs when you have questions about a specific API function.

In your case, you have to add the ?fields=anime_statistics parameter to the endpoint's URL. You can find all possible values you can pass clicking here and selecting "Response schema: */*" or "Content type: application/json".

Just keep in mind that MAL's documentation contains several typos and minor errors. You should always double-check all endpoints you're going to use. ;-)
HTCPCP/1.0  ★ MetaMAL  ★ Picture credits: Kieed & 1041uuu
Nov 7, 2020 11:50 AM

Offline
Oct 2009
7752
What I want: to get the list of the logged in user using the userscript. Or for starters, get my own list with the userscript
Do I understand correctly, that in order to access the info on the list, I need both Access Token and Authorization Code?
You say "Clicking on the previous link would redirect the user to an authorisation page", but I don't understand, the userscript isn't supposed to make the user leave the page he's currently on. How and where is the authorisation page even supposed to appear?

This code doesn't work, but just so that we have something to start with: http://pastebin.com/w8TPfHy1 – what do I need to add to get the Authorization Code?
I'm a noob in this so sorry if I ask something very obvious
Nov 8, 2020 6:19 AM
四十二

Offline
Mar 2016
488
Serhiyko said:
Do I understand correctly, that in order to access the info on the list, I need both Access Token and Authorization Code?
You say "Clicking on the previous link would redirect the user to an authorisation page", but I don't understand, the userscript isn't supposed to make the user leave the page he's currently on. How and where is the authorisation page even supposed to appear?

This code doesn't work, but just so that we have something to start with: http://pastebin.com/w8TPfHy1 – what do I need to add to get the Authorization Code?
I'm a noob in this so sorry if I ask something very obvious

Unfortunately, the OAuth protocol is poorly suited for userscripts. It's not impossible to use it, but it requires some effort on your end.
Basically, it's a two-steps process: first, the user needs to authorise your application, and then you have to obtain an Access (and Refresh) Token which you can use to access the API on behalf of the user who completed the procedure.

The Authorisation Code is a one-time code. It's as if MAL was telling you: «Hey! A new user authorised your application to access her/his anime list and related functions. If you're interested, then send us back this Authorisation Code and we will give you an Access Token and a Refresh Token you can use.» Once you've obtained the tokens, you can discard the Authorisation Code.

Now, as a userscript developer, you have two problems which you have to solve if you want to access the API: how to receive the Authorisation Code, and how to circumvent the Same Origin (CORS) policy enforced by modern browsers. The solution is simple for native and web applications, but not for userscripts.

During the authorisation procedure, MAL's servers will send the Authorisation Code to a well-defined URL which you must set in your API dashboard. You need to find a way to catch that request and tell the code to your userscript. An easy solution would be to redirect the users to a blank page or a page that simply prints the Authorisation Code contained in the query string of the URL; then, the users have to copy-paste it somewhere your application can read it.
Alternatively, you can probably tell your userscript to catch all connections targeting the Redirect URL and automatically read the Authorisation Code; however, I've never created a browser's userscript, so I don't know how difficult it would be.

The second problem is more difficult to solve and it should be fixed by MAL's dev team. I discussed about it in #36, I suggest you to take a look. In short, the API server is missing the CORS headers required to call the endpoints directly from the browser. I already reported this issue, but I have no idea when it will be fixed. In the meantime, I suggested an easy way to bypass the Same Origin policy in #36.
HTCPCP/1.0  ★ MetaMAL  ★ Picture credits: Kieed & 1041uuu
Nov 8, 2020 4:55 PM

Offline
Oct 2009
7752
ZeroCrystal said:
Unfortunately, the OAuth protocol is poorly suited for userscripts. It's not impossible to use it, but it requires some effort on your end.
Basically, it's a two-steps process: first, the user needs to authorise your application, and then you have to obtain an Access (and Refresh) Token which you can use to access the API on behalf of the user who completed the procedure.

The Authorisation Code is a one-time code. It's as if MAL was telling you: «Hey! A new user authorised your application to access her/his anime list and related functions. If you're interested, then send us back this Authorisation Code and we will give you an Access Token and a Refresh Token you can use.» Once you've obtained the tokens, you can discard the Authorisation Code.

Now, as a userscript developer, you have two problems which you have to solve if you want to access the API: how to receive the Authorisation Code, and how to circumvent the Same Origin (CORS) policy enforced by modern browsers. The solution is simple for native and web applications, but not for userscripts.

During the authorisation procedure, MAL's servers will send the Authorisation Code to a well-defined URL which you must set in your API dashboard. You need to find a way to catch that request and tell the code to your userscript. An easy solution would be to redirect the users to a blank page or a page that simply prints the Authorisation Code contained in the query string of the URL; then, the users have to copy-paste it somewhere your application can read it.
Alternatively, you can probably tell your userscript to catch all connections targeting the Redirect URL and automatically read the Authorisation Code; however, I've never created a browser's userscript, so I don't know how difficult it would be.

The second problem is more difficult to solve and it should be fixed by MAL's dev team. I discussed about it in #36, I suggest you to take a look. In short, the API server is missing the CORS headers required to call the endpoints directly from the browser. I already reported this issue, but I have no idea when it will be fixed. In the meantime, I suggested an easy way to bypass the Same Origin policy in #36.

This is too complicated... I would appreciate to see a working userscript that uses the new API, so that I could just copy-paste the code and use for my needs (but with my own Client ID of course). In the meantime, I've just tweaked the code a little to simply directly parse the .html list. It now takes a bit longer to load but whatever, it only matters that it works, at least for me. Also doesn't support lists with Modern Styles now, but I don't use one, so don't care
If anyone's curious, here is the userscript in question: http://greasyfork.org/scripts/12412
Nov 9, 2020 4:38 AM
四十二

Offline
Mar 2016
488
Serhiyko said:
This is too complicated... I would appreciate to see a working userscript that uses the new API

I understand you, I'm not a fan of the current state of the API too. We can only wait and see what will happen in the future.

@hacker09, if I remember correctly, you were also developing a userscript using the new API. Did you manage to build a working script which you can show to @Serhiyko?
HTCPCP/1.0  ★ MetaMAL  ★ Picture credits: Kieed & 1041uuu
Nov 9, 2020 4:48 AM

Offline
Dec 2019
3531
@ZeroCrystal

Thanks for the quote...
Well during our conversation you ended up developing the important parts of it. I would just need to "gather together" all the codes you did, and make them work for everyone, automatically, and publish that on my greasyfork account.

But yeah I still can do it if you and Serhiyko want's to, I really like you guys.

@Serhiyko Here are "my tutorials", on how to "deploy" and get all the stuff you need to use the api. (read ZeroCrystal's replies if you don't understand something or have the same questions I had.)
https://myanimelist.net/forum/?topicid=1850649&show=0#msg60421964
https://myanimelist.net/forum/?topicid=1850649&show=0#msg60424205

@ZeroCrystal
I'm just not sure if I make a script that auto generates the bearer key etc would be helpful for others too. If you also added my script link on your "API tutorial" I would, even more likely, make the tampermonkey script that automates all this "getting the api to work" process.

I was thinking on 2 scripts, one would automate this "get api process", the other one would just use the mal api, both of them would end up being really similar in their source codes I guess, so that's why I talked about the script that would automate this "get api process" and shared that 2 forum links with Serhiyko.
hacker09Nov 9, 2020 5:11 AM
Click here to see My Tampermonkey Scripts For MAL

If you like my work, please consider supporting it!
Cryptos / Patreon / Ko-Fi / BuyMeaCoffee https://cyber-sec0.github.io
Nov 14, 2020 8:58 PM
Offline
Nov 2020
2
I'm currently working on getting the token, I made it to the part where it asks user to authorize my app.

When i got the authorization code
i sent a POST request to https://myanimelist.net/v1/oauth2/token
with the following Header and Body:

Header:
Content-Type: application/x-www-form-urlencoded

Body:
client_id: my_client_id
client_secret: my_client_secret
grant_type: "authorization_code"
code: "MY_AUTH_CODE_AFTER_USER_AUTH"
code_verifier: "MY_PKCE"

but i get this response json instead

{"error":"unsupported_grant_type","message":"The authorization grant type is not supported by the authorization server.","hint":"Check the `grant_type` parameter"}

I even double checked by sending the request through cURL

curl -X POST -H "Content-Type: application/x-www-form-urlencoded" -d "client_id=my_client_id&client_secret=my_client_secret&grant_type=authorization_code&code=MY_AUTH_CODE_AFTER_USER_AUTH&code_verifier=MY_PKCE" https://myanimelist.net/v1/oauth2/token

and i still get the same result.

Am I doing something wrong? Im pretty much clueless atm.
Nov 15, 2020 6:17 AM
四十二

Offline
Mar 2016
488
Looz0001 said:
I even double checked by sending the request through cURL

curl -X POST -H "Content-Type: application/x-www-form-urlencoded" -d "client_id=my_client_id&client_secret=my_client_secret&grant_type=authorization_code&code=MY_AUTH_CODE_AFTER_USER_AUTH&code_verifier=MY_PKCE" https://myanimelist.net/v1/oauth2/token

and i still get the same result.

Am I doing something wrong? Im pretty much clueless atm.

I tried running the following curl command and it successfully returned a new token:
curl -d "client_id=123&client_secret=abc&code=def&code_verifier=987&grant_type=authorization_code" https://myanimelist.net/v1/oauth2/token

The problem probably lies elsewhere. Most implementations of the OAuth protocol define the Code Challenge as a hashed version of the Code Verifier (SHA256), but this is not how it was implemented by MAL. The Code Verifier and Code Challenge must be exactly the same string. Maybe this is the cause of your problem.

Also, keep in mind that the Authorisation Code is only valid for a few minutes and can only be used once. If you've run your code or curl command several minutes after you've obtained an Authorisation Code or you've been using the same Authorisation Code repeatedly, then this is what you're doing wrong.
ZeroCrystalNov 15, 2020 6:20 AM
HTCPCP/1.0  ★ MetaMAL  ★ Picture credits: Kieed & 1041uuu
Nov 15, 2020 6:29 PM
Offline
Nov 2020
2
ZeroCrystal said:

I tried running the following curl command and it successfully returned a new token:
curl -d "client_id=123&client_secret=abc&code=def&code_verifier=987&grant_type=authorization_code" https://myanimelist.net/v1/oauth2/token

The problem probably lies elsewhere. Most implementations of the OAuth protocol define the Code Challenge as a hashed version of the Code Verifier (SHA256), but this is not how it was implemented by MAL. The Code Verifier and Code Challenge must be exactly the same string. Maybe this is the cause of your problem.

Also, keep in mind that the Authorisation Code is only valid for a few minutes and can only be used once. If you've run your code or curl command several minutes after you've obtained an Authorisation Code or you've been using the same Authorisation Code repeatedly, then this is what you're doing wrong.


Thanks for the reply! I double checked the way I sent the request and I have found my issue.

I was developing my app with NodeJS and I sent the request with node-fetch, apparently I did not enter the parameters correctly hence submitting the request without specifying "Content-Type: application/x-www-form-urlencoded" in my request header.
Nov 16, 2020 2:14 AM
四十二

Offline
Mar 2016
488
Looz0001 said:
Thanks for the reply! I double checked the way I sent the request and I have found my issue.

I see. Good luck with your project!
HTCPCP/1.0  ★ MetaMAL  ★ Picture credits: Kieed & 1041uuu
Nov 18, 2020 10:49 PM
Offline
Nov 2019
1
For those who are looking for a NodeJs example, this might be helpful. node-myanimelist-oauth-example
Nov 22, 2020 12:21 PM
Offline
Nov 2020
2
See this topic to obtain a token with a bash script.
Nov 26, 2020 1:56 AM
Offline
Nov 2020
1
用postman 发送POST请求获取token ,报以下的错,https://myanimelist.net/v1/oauth2/token
{
"error": "invalid_request",
"message": "The request is missing a required parameter, includes an invalid parameter value, includes a parameter more than once, or is otherwise malformed.",
"hint": "Authorization code has expired"
}
Nov 26, 2020 4:11 AM
四十二

Offline
Mar 2016
488
jupitergood said:
{
    ...
    "hint": "Authorization code has expired"
}

After you've obtained an Authorisation Code, you must use it almost immediately. Authorisation Codes will expire after a few minutes, so you've probably run your Postman query too late.
HTCPCP/1.0  ★ MetaMAL  ★ Picture credits: Kieed & 1041uuu
Nov 30, 2020 9:12 AM
Offline
Sep 2011
28
ZeroCrystal said:

Just remember that the website must be served via HTTPS, or you won't be able to receive the authorisation code. Good luck with the project!


So, I finally got around to do some more in-depth coding in that regard but, unfortunately, I seem to be stuck on something I can't debug.

I am pretty much taking the vanilla PKCE Challenge example on GitHub below to create everything I need and then request the authorization endpoint to get the authorization code that then my users can use to add to their plugins. So far so good.

I start the request and get the Basic HTTP login box in which I enter my username and password and click OK and the only thing that happens is that I get another login box. I can keep "logging in" as much as I want without any change. Keep getting the Login box. I even created a new App for a new Client_ID thinking that maybe something internally went wrong with my old one, but without any change in its behaviour.

Funnily enough, I can't even delete my old Clients because then I get a "400 Bad Request"

Maybe you have some Idea where I can look?

https://github.com/aaronpk/pkce-vanilla-js
Nov 30, 2020 9:39 AM
四十二

Offline
Mar 2016
488
Fribbtastic said:
I am pretty much taking the vanilla PKCE Challenge example on GitHub below to create everything I need and then request the authorization endpoint to get the authorization code that then my users can use to add to their plugins.

https://github.com/aaronpk/pkce-vanilla-js

The GitHub example you've linked uses a different OAuth schema where the Code Challenge is a hashed version (SHA-256) of the Code Verifier. Instead, MAL requires that both the Code Challenge and the Code Verifier must be the exact same string. Similarly, there're some other parameters that need to be altered (e.g. "code_challenge_method").

Fribbtastic said:
Maybe you have some Idea where I can look?

Before I suggest you something different, can you try testing your application using a fixed and pre-generated Code Verifier/Code Challenge? For instance, you can use the string given by repeating 'A' × 128 times, which you can copy-paste it from here.
HTCPCP/1.0  ★ MetaMAL  ★ Picture credits: Kieed & 1041uuu
Nov 30, 2020 9:51 AM
Offline
Sep 2011
28
ZeroCrystal said:
The GitHub example you've linked uses a different OAuth schema where the Code Challenge is a hashed version (SHA-256) of the Code Verifier. Instead, MAL requires that both the Code Challenge and the Code Verifier must be the exact same string. Similarly, there're some other parameters that need to be altered (e.g. "code_challenge_method").


I read about the code_challenge_method to being only plain so that is also set to plain instead of S265 but this doesn't seem to be the issue.

ZeroCrystal said:

Before I suggest you something different, can you try testing your application using a fixed and pre-generated Code Verifier/Code Challenge? For instance, you can use the string given by repeating 'A' × 128 times, which you can copy-paste it from here.


I copied the 128xA and replaced the generated code verifier and code challenge with it. The authentication URL is called with it but still end up in a login loop.

I will send you a message with the actual running code so that we are on the same page.
Dec 1, 2020 7:46 AM
四十二

Offline
Mar 2016
488
Fribbtastic said:
I will send you a message with the actual running code so that we are on the same page.

We solved this issue via PMs, but I thought that sharing the cause of the problem might help someone else.

@Fribbtastic's problem was that the Redirect URL he registered in the API panel matched the one he specified in the Authorisation URL except for the letter case.

Technically speaking, domain names are not case sensitive. For instance, both myanimelist.net and MYanimeLIST.nEt correspond to the same domain and DNS entries. However, this equivalence is ignored by the API back-end. For this reason, using a Redirect URL with a different casing than the one defined in the API panel will result in an error (or, rather, in a weird response from MAL servers).

Please, double-check your Redirect URLs if you've encountered a similar problem. Pending slashes will also result in the same error (e.g. myanimelist.netmyanimelist.net/).
HTCPCP/1.0  ★ MetaMAL  ★ Picture credits: Kieed & 1041uuu
Dec 1, 2020 8:58 AM
Offline
Nov 2020
2
Hi, I'm having a hard time getting a request to get an anime list from the API server in python. Is there any chance I could see an example of it? Also, is there a way to extract the JSON, XML, HTTP, info as well. I'm using the API for a school project, and I was having a hard time with those two things.
Dec 1, 2020 9:05 AM
四十二

Offline
Mar 2016
488
quake_01 said:
Hi, I'm having a hard time getting a request to get an anime list from the API server in python. Is there any chance I could see an example of it?

Sure thing! I wrote a minimal Python programme covering both the OAuth authorisation procedure (which is a one-time step) and the use of the API (using the "Get my user information" endpoint). You can find it here: gitlab.com/-/snippets/2039434.
HTCPCP/1.0  ★ MetaMAL  ★ Picture credits: Kieed & 1041uuu
Dec 1, 2020 9:41 AM
Offline
Nov 2020
2
Oh okay!! So, I have the access token now, and I think this is where I was stuck before. So, to use a get request to get an anime list would be similar to when you tested the API to request your profile information?
Reply Disabled for Non-Club Members
Pages (4) « 1 [2] 3 4 »

More topics from this board

» I built a spotify-styled 'MyAnimeList Wrapped' for a yearly review of your anime and manga

XAvishkar - Dec 14

1 by Joeliazeers »»
Dec 17, 1:01 PM

» [Repost] list of all relation_type and media_type.

Mr_UnknownOtaku - Dec 8

4 by -DxP- »»
Dec 12, 8:43 AM

» How to get author name?

EdibleMuffin - Feb 12

4 by XAvishkar »»
Dec 8, 9:52 AM

» 401 Unauthorized when doing authorization flow

Konng_ - Nov 16

2 by Konng_ »»
Nov 28, 3:24 PM

» [discontinued] I made a webapp to compare plan-to-watch lists

daux - Apr 16, 2022

33 by daux »»
Oct 2, 4:17 PM
It’s time to ditch the text file.
Keep track of your anime easily by creating your own list.
Sign Up Login