Mural API authentication with curl/postman

CharekC
edited October 2022 in Mural API

I want to programmatically create sticky notes in a new mural canvas with something like curl/postman

I was reading about authentication/authorization to invoke mural apis. I am not creating an "app" per se but a script (maybe in python for example).

https://developers.mural.co/public/docs/oauth

I am not well versed in OAuth but it appears to be a series of exchanges to get the token required to invoke the apis.

So how can I get a token with just curl/postman without having to write an app and register it according to

https://developers.mural.co/public/docs/register-your-app

Tagged:

Answers

  • Hello @CharekC!

    We have a detailed guide to test MURAL API using Postman here (https://developers.mural.co/public/docs/testing-with-postman). But to your point, it does require you to first register your app to obtain Client ID and Client Secret. We'll make a note of it for the future but for now please go ahead and register your app - it should take <5 mins to obtain your client ID and client secret.

    Best,

    Anuj

  • Meghan
    Meghan ✭✭✭

    @CharekC, is this ballpark to what you're looking for? 👆️

  • Hi @MeghanB

    My use case is headless/no browser/script to interact with the mural apis to create something.

    So for example the following use case/pseudo code: 

    1. setup array for sticky notes [mynote1, mynote2 ... ] (from file or external service etc)
    2. curl/python request to https://app.mural.co/api/public/v1/authorization/oauth2/ to get authorization code in response. Provide clientId in request
    3. curl/python request to https://app.mural.co/api/public/v1/authorization/oauth2/token to get access token in response. Provide clientId, clientSecret and auth code in request
    4. Then use curl/python request for apis in https://developers.mural.co/public/reference/createstickynote with <access token> as the value for 'Authorization: Bearer ....'

    So the instructions seem to point to app setup which I am confused how the following would apply to my use case:

    • App Name
    • App Description
    • Logo URL
    • Documentaion
    • Homepage URL
    • Redirect URLs
    • Reject URL
    • Allowlist Domains


  • Anuj
    Anuj admin
    edited April 2022

    Hello @CharekC,

    We are working on simplifying the process of creating an app to obtain Client ID and Client secret. In the meantime, you can use representative values for the above fields and get client ID and secret.

    Also, a bit more context on Oauth:

    We use a standard OAuth2 authorization code grant flow. A key part of the flow is the user logging into the "authorization server" (MURAL) using their MURAL credentials and consenting to have the external app access their MURAL data (according to the indicated scopes). In your oringal flow, the user interaction happens after step 2: the response is a 302 Redirect to log in to MURAL.

    This should be documented well-enough at https://developers.mural.co/public/docs/oauth.

    Best,

    Anuj

  • Meghan
    Meghan ✭✭✭

    @CharekC, I'll hang out in the wings, but let me know if Anuj's support helps!

  • Hi @Anuj and @MeghanatMURAL

    I have the same use case as @CharekC and still can't find a way to make it work (or it's not possible yet?).

    I have read all the available docs pages I could find on this subject but I can't find anything on machine to machine authorization, I would expect to find info about the OAuth "client_credentials" grant type, which would provide a short lived token my process could use, isn't it implemented?

    I tried to post to https://app.mural.co/api/public/v1/authorization/oauth2/token with the client id, client secret and grant_type=client_credentials but didn't succeed.

    Please help.

  • +1. Looking into this scenario as well.

  • What would be great is on one of the Python workbooks in the API git repo, eg here:

    Where is says "Step 2: Collect your OAuth token" to have an example of actually getting the token.

  • Anuj
    Anuj admin

    Hi @sparkademy - it will be great to understand what you are trying to solve for using MURAL API and where exactly are you getting stuck. Please feel free to book a time that suits you on my calendar below:

    https://calendly.com/anuj-jain-mural/mural-api-user-feedback

    Best,

    Anuj

  • Hi @Anuj

    Here's our use case:

    We will run workshops on our platform with teams from people from other companies so we own a Mural account with templates in it (Sparkademy account).

    I want to create a mural (whiteboard) for each team based on a template, this is what I expect my backend server to do with the Mural API. It will create the teams with people who do not necessarily have a Mural account and create a mural board for the team. They would access the team mural with a visitor link.

    That's why I only have machine to machine interaction and the access token would be used in my server when creating the teams and murals from templates.

  • FYI just posted Python code here that will get a Mural token:

    https://community.mural.co/discussion/comment/2611#Comment_2611

  • @Anuj I already have the App created as I mentioned in my first comment, I tried using the client id and secret to call the API to get the access token. I got the error below:

    {
        "error": "unauthorized_client",
        "error_description": "Client app is not set up or authorized to use this grant_type"
    }
    

    I tried to post to https://app.mural.co/api/public/v1/authorization/oauth2/token with the client id, client secret and grant_type=client_credentials, following the OAuth specification to get an access token.

    What is the endpoint in the API I can call to get this access token you mentioned?

    Also the code posted from @rambutan2000 doesn't seem to work from me because it uses the webbrowser lib which is not available in the server environment. It seems its a hack to get the token.

  • rambutan2000
    edited July 2022

    AFAIK the only way to do it is to have a HTTP/HTTPS server setup and be accessible by your script, so when the Mural auth page calls your redirect you can get the full redirect URL including the auth code. Like stated here in the "Web Application Flow" section: https://requests-oauthlib.readthedocs.io/en/latest/oauth2_workflow.html#web-application-flow

    You don't need to use webbrowser, here's a similar example using Flask:

    Also I'd highly recommend using requests-oauthlib https://pypi.org/project/requests-oauthlib/

    Here's the general steps I take for my scenario:

    1. Setup your Mural app, get your client id and secret and set your redirect URL to http://localhost:8088. That obvi only works if you have your web server running on your local machine.
    2. Get the Authorization URL. In my script it's: authURL, state = mural.authorization_url(authBaseURL)
    3. Start your local web server
    4. Call the Authorization URL in the default browser. This should display the Mural access page. When you click accept it then triggers the redirect back to your local web server
    5. In your web server's GET callback check for errors and save the full path that was used to redirect to your server.
    6. Use the redirect path captured in step 5 to get the token: token = mural.fetch_token(tokenURL, client_secret=clientSecret, authorization_response=LocalServer.authResponse)

    Right now I'm not sure if it's possible to automate step 4.

    Also note that once you get the token from step 6 and try to use it in a call, you need to pass token["access_token"] to the API calls.

  • @rambutan2000 It seems like your use case is different than mine. I'm running my script in a server (cronjob) I can't rely on running a web server (I shouldn't need to) or a web browser like you mentioned in step 4.

    It looks like the OAuth implementation for Mural is missing the client_credentials grant type which is what we use for machine to machine communication. If it was I could get an access token by posting to https://app.mural.co/api/public/v1/authorization/oauth2/token with the client id, client secret and grant_type=client_credentials.

    See more here: https://www.oauth.com/oauth2-servers/access-tokens/client-credentials/

    This back and fourth you're doing shouldn't be necessary, this is a workaround the correct approach.