Api_secret generate by programmatically not work

I am writing a client app (reactjs) which consume some data in Frappe.
The idea is to call login API (username, password)
=> Then receive api_key + api_secret to make some API calls.
Which using token base authenticate as “token <api_key>:<api_secret>”

I followed some tutorials about user login and generate api_secret and has a login API.
The API look like:

@frappe.whitelist( allow_guest=True )
def login(username, password):
    try:
        login_manager = frappe.auth.LoginManager()
        login_manager.authenticate(user=username, pwd=password)
        login_manager.post_login()
    except frappe.exceptions.AuthenticationError:
        frappe.clear_messages()
        frappe.local.response["message"] = {
            "success_key":0,
            "message":"Authentication Error!"
        }

        return

    api_generate = generate_keys(frappe.session.user)
    user = frappe.get_doc('User', frappe.session.user)

    frappe.response["message"] = {
        "success_key":1,
        "message":"Authentication success",
        "sid":frappe.session.sid,
        "api_key":user.api_key,
        "api_secret":api_generate,
        "username":user.username,
        "email":user.email
    }



def generate_keys(user):
    user_details = frappe.get_doc('User', user)
    api_secret = frappe.generate_hash(length=15)
 
    if not user_details.api_key:
        api_key = frappe.generate_hash(length=15)
        user_details.api_key = api_key

    user_details.api_secret = api_secret
    user_details.save()

    return api_secret

However after login successfully and the above api return api_secret.
I used it to call others API but the api_secret is invalid.
Even I check the api_secret using the API “/api/method/frappe.auth.get_logged_user”, it still does not work.

(The API secret generated by Frappe UI works, but generated by programmatically as above does not)

Please help if I get wrong at some steps to generate API secret.

Thank you for your support.

you have to use it as follows

token api_key:api_scret
1 Like

Hi @Max_Power,

Adding in @mohitchechani answer, If you haven’t checked then please check the documentation of Token Based Authentication.

And

By adding logging statements, you can check if the generated API key and secret match the ones you expect.

def generate_keys(user):
    user_details = frappe.get_doc('User', user)
    api_secret = frappe.generate_hash(length=15)
 
    if not user_details.api_key:
        api_key = frappe.generate_hash(length=15)
        user_details.api_key = api_key

    user_details.api_secret = api_secret
    user_details.save()

    frappe.logger().info(f"Generated API Key: {user_details.api_key}, API Secret: {api_secret}")

    return api_secret

Please customize the code and check it.

I hope this helps.

Thank You!

Thank you for your reply @NCP @mohitchechani
Let I summary my check:

  1. Generate API secret by code (Failed):
    As you see, call the login API and the code generated the API Secret, and I use it to call other API, simply call the /get_logged_user it returns the failed results

  2. Generate API secret by Admin UI (Sucess):
    Generate by UI and use the secret, then use it to call /get_logged_user, it return successfully.

Please help and tell me if I have something wrong
Thank you for your support.

Hi,
Any update on this please?
This still does not work at my side.

Thanks,

I see that you wrote your own API method. Why won’t the default work? Is it not “whitelisted”?
/api/method/frappe.auth.get_logged_user

Hi @Colin_Vander_Veen ,
Thank you for your reply.

(1). The “/api/method/frappe.auth.get_logged_user” is just one of the ways I used to check if the auth token works or not
Maybe, instead of that API, I can call some other APIs to check the token, (e.g call API to Get library authors…)

(2). The main problem I show here is that the login API /library_management.customapi.login - it actually create, save and return a secret token, but I cannot use it to call any API as mention in (1).


I have a client app (reactjs) contains a login page, which will receive username/password to call this Login API, then returns a secret token.
=> So that I can use token to make further API to get/post data to Frappe as a back-end.
Using the Authentication header: “token <api_key>:<api_secret>”

So please help on this.
Or if you have any way for the Reactjs client app to login/get token/ then make further APIs call to frappe, please tell me.

Thanks,

Thanks for the info. I gave up and have just created a cron scheduler to log my gateway ‘user’ in each day.

The postman screenshot shows GET request, that means the generated API key is not actually stored in database. You need to do a POST request.

https://frappeframework.com/docs/user/en/api/database#database-transaction-model

3 Likes

Nice @ankush , GET is the root cause. Changed to POST everything works well.
Thank you very much.