使用Aqueduct的OAuth错误,ManagedPropertyType不匹配

时间:2017-06-29 13:17:46

标签: dart aqueduct

我正在使用随新创建的Aqueduct项目提供的OAuth钩子。我的数据按以下方式进行URI编码:

var form = body.keys
    .map((key) => "$key=${Uri.encodeQueryComponent(body[key])}")
    .join("&");

尝试注册用户时收到以下错误:

DataModelException:_User上属性username的类型不匹配,期望的可分配类型与ManagedPropertyType.string匹配,但得到了_ImmutableList。 #0 ManagedValueBacking.setValueForProperty

请求如下所示:

HttpRequest.request('/register', method: 'POST',
    sendData: form,
    requestHeaders: {
        "Content-Type": "application/x-www-form-urlencoded",
        "Authorization": "Basic $clientCredentials"
}).then((HttpRequest req) {
    ...
}).catchError((e) => _handleError(...));

我不太确定为什么将正文解释为ImmutableList。

我一定错过了什么!

1 个答案:

答案 0 :(得分:0)

/ register端点需要JSON数据。

HttpRequest.request('/register', method: 'POST',
    sendData: JSON.encode(body),
    requestHeaders: {
        "Content-Type": "application/json; charset=utf-8",
        "Authorization": "Basic $clientCredentials"
});

不幸的是,这还不是很清楚 - HTTPController默认允许JSON和表单数据以及现在更改它可能会破坏某人的代码;不过,模板可以更好地完成restricting input to JSON only

此错误的具体原因是表单数据和查询参数可以包含同一键的多个条目。 Aqueduct将表单数据和查询参数视为相同,并始终将这些类型的输入解析为列表。由于RegisterControllerQueryController<T>,因此需要一个JSON请求正文,其中每个值都不是列表。

您可以随时修改RegisterController以仅采用表单数据,而不是切换到JSON:

class RegisterController extends HTTPController {
  RegisterController(this.authServer) {
    acceptedContentTypes = [new ContentType("application", "x-www-form-urlencoded")];
  }
  AuthServer authServer;

  @httpPost
  Future<Response> createUser(
    @HTTPQuery("username") String username,
    @HTTPQuery("password") String password) async {

    var query = new Query<User>()
      ..values.username = username
      ..values.password = password;

    var salt = AuthUtility.generateRandomSalt();
    ...

注意:授权的端点需要表单数据(根据OAuth 2.0规范),但新项目中的所有其他内容都需要JSON数据。