API経由でのメール更新不可:invalid_accessエラー

Hi Guys,

Im getting an error when trying to use the API to update email.
I have looked at the logs and can see the following:

Started PUT “/discussion/users/davetest/preferences/email.json” for xx.xx.xx.xx at 2018-05-11 12:22:11 +0000

Processing by UsersEmailController#update as JSON

Parameters: {“api_key”=>;"[FILTERED]", “api_username”=>;“daveAdmin”, “email”=>;“[new.email@example.com](mailto:new.email@example.com)”, “username”=>;“davetest”}

Can’t verify CSRF token authenticity.

This is a PUT request, but looking at the scopes below, doesnt seem like PUT is supported for the WRITE scope? surely im misunderstanding, so could someone please assist?

I have re-generated the all-user api-key, also created specific user api-keys to use, but same result.

SCOPES = {
read: [:get],
write: [:get, :post, :patch],
message_bus: [[:post, ‘message_bus’]],
push: nil,
notifications: [[:post, ‘message_bus’], [:get, ‘notifications#index’], [:put, ‘notifications#mark_read’]],
session_info: [[:get, ‘session#current’], [:get, ‘users#topic_tracking_state’]]
}

Can you verify the content-type that you are making the API request as? It needs to be

"Content-Type: multipart/form-data;"

If it is not that content type you may see the CSRF token error.

Hi, thanks for the reply.
I actually had tried it both with ‘application/json’ and ‘application/x-www-form-urlencoded’ and neither worked. I have now tried it with what you suggested (via postman) and getting:

“You are not permitted to view the requested resource. The API username or key is invalid.”

I have regenerated the global api key that is used for “all users” and using it with my own username, which is an admin too…

shahid

Here is an example of my postman request maybe you can spot any differences with what you are doing? I’m also using the “all users” key with an admin username.

yes, its the same, im using the Postman API collection supplied by discourse. So using it as suggested. I will try again tonight and see if i get any different results. Will update when ive tried. Thanks for assisting, much appreciated. Do let me know if you have any other idea.

私もこの問題に直面しています。サインインに OAuth プロバイダーを使用していることが原因で、この特定のページがブロックされているのでしょうか?

おそらく OAuth プロバイダーは関係ありません。API キーを使えばそれを回避できるからです。

API リクエストのコードを共有してもらえませんか?

Python のコード:

import json
import requests
import time

my_token = ''

url_base = '<>'
update_email = url_base + "users/<my_username>/preferences/email.json"

headers = {
    "Content-Type": "multipart/form-data",
    'user-agent': 'my-app/0.0.1',
    'Api-Key': my_token,
    'Api-Username': '<my_username>'
}

data = {
  "email": "<new_email>"
}

response = requests.put(update_email, data=data, headers=headers)

print(response.text)

追記: ユーザーのグループ設定などを行う非常に似たコードは動作したため、キーとユーザー名の組み合わせ(管理者権限を持つユーザー)は問題ありません。

追記 2: フォーラム内の他の閲覧から推測すると、これはデータベースに直接(あるいはコンソール経由で)行う必要があり、当社には不可能です。

これについてさらにご意見はありますか?私の考えでは、管理者権限を持つ人は誰のメールアドレスでも設定できるはずです。

どうしてですか?API を定義している既存の Web UI ではこれは不可能だと思われます。したがって、実行できません。

つまり、UX/API はユーザーのメールアドレスを任意の値に設定できるようにするべきだ、という意味ですね。(現在それが可能だと信じているわけではありませんが。)

プロフィールを編集して新しいアドレスを入力することで、変更を開始できます(UX およびおそらく API 経由で)。ただし、ユーザーがメール内のリンクをクリックするまで、変更は反映されません。これで十分でしょうか?もし不十分であれば、コンソールまたはプラグインから変更を行う必要があります。

その通りです。

UX でメールアドレスの編集を入力する際(これはユーザーのプロフィールから直接リンクがなく、https://<discourse>/u/<username>/preferences/email という直接 URL のみでアクセス可能です)、「変更」をクリックすると以下のエラーが表示されます。

これは管理者である自分のアカウントでも発生しています。メールは届きません。

私も今、この段階に到達しました…

@pfaffman: プロフィールでメールアドレスを変更できることはおっしゃっていましたが、email editable が設定されている必要があるのですね?

管理者または管理用 API 呼び出しで、ユーザー自身がメールアドレスを変更できる場合を除き、メールアドレスの変更を開始する方法はないと聞きました。ユーザーによる変更を許可する場合、確認メールを送信し、変更をユーザーが承認する必要があるのは確かですが、それで問題ありません。

私のユースケースは、ユーザーを別のアプリから API を介して管理したいというものです。そのため、Discourse 上ではユーザー自身がメールアドレスを変更できないようにしたいと考えています。

Single Sign Onを実装し、他のアプリをログインのソースとして設定することは可能でしょうか?

ご要望の機能を実現する sso overrides email という特定の SSO 設定があります。SSO が設定されていれば、sync_sso エンドポイントを使用して新しいメールアドレスを渡すことができます。

@blake さん、ありがとうございます。それは挑戦的ですが、楽しいですね :wink:

Discourse からパスワードを Identity Hub にインポートしないといけないなんて…おやまあ。

私の元のシナリオには、3 段階の手順で対応しました。メールの編集を有効化し、メールアドレスの変更を開始し、メールの編集を無効化する、というものです。少し大げさな気もしますが、機能しています。

SSO のシナリオについても考えてみます。