Jeer
@Jeer
уверенный пользователь

Почему не работает проверка подписи в vk mini apps?

Добрый день,
Сделал мини-приложение в контакте. Там авторизация происходит следующим образом: когда загружается приложение в айфрейме, в query параметрах передаются разные значения, например, айди пользователя. И есть параметр sign, который рассчитывается по сложной формуле с учетом секретного ключа. Примеры из документации для других языков. Для c# я нашел один пример на просторах интернета и такая история, что он работает наполовину. То есть, для первого захода этот алгоритм работает, и у меня прикопан рабочий пример для этого кода. Но когда я дал разрешение на список друзей, параметры немного поменялись и код перестал работать. При этом как его отлаживать, я не пойму, типа, не совпадает итоговое значение и всё. Я поперетыкал всё, что только возможно, думал может проблема в UrlEncode/UrlDecode и чем-то подобном, так как запятая добавилась, которая в url-е читается как %2c, например, но я так и не смог найти ошибку.

public bool IsSignValid(string queryString)
    {
        var queryParameters = HttpUtility.ParseQueryString(queryString);
        var orderedKeys = queryParameters
            .AllKeys
            .Where(p => p != null && p.StartsWith("vk_"))
            .OrderBy(p => p);

        var signParams = new Dictionary<string, string>();
        foreach (var key in orderedKeys)
        {
            signParams[key] = queryParameters[key];
        }

        var signString = string.Join("&", signParams
            .OrderBy(x => x.Key)
            .Select(x => HttpUtility.UrlEncode(x.Key) + "=" + HttpUtility.UrlEncode(x.Value)));
        var token = HmacHash(signString, _options.PrivateKey);
        var isRequestValid = token.Equals(queryParameters["sign"]);
        return isRequestValid;
    }

    public static string HmacHash(string message, string secret)
    {
        var messageBytes = Encoding.UTF8.GetBytes(message);
        var keyBytes = Encoding.UTF8.GetBytes(secret);

        using var hash = new HMACSHA256(keyBytes);
        var hashMessage = hash.ComputeHash(messageBytes);
        return Convert
            .ToBase64String(hashMessage)
            .Replace('+', '-')
            .Replace('/', '_')
            .Replace("=", string.Empty);
    }
  • Вопрос задан
  • 30 просмотров
Пригласить эксперта
Ответы на вопрос 1
Jeer
@Jeer Автор вопроса
уверенный пользователь
Ну короче тема не особо популярна, но решене все же выложу (сравнил что генерит node.js и нашел проблему).
var signString = string.Join("&", signParams
            .OrderBy(x => x.Key)
            .Select(x => x.Key + "=" + WebUtility.UrlEncode(x.Value)));

WebUtility.UrlEncode заменяет запятую на %2C, в то время как HttpUtility заменяет на %2c, что критично
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы