首页 > 解决方案 > FeathersJS Twitch OAuth 401 未经授权

问题描述

我是 FeathersJS 的新手。我尝试使用 Twitch 设置 OAuth 登录。我创建了一个 twitch oauth 应用程序,并使用 github 登录做了与此处相同的操作。我想将用户保存在我的 MongoDB 数据库中,但在登录 twitch 后我被重定向到http://localhost:3030/#error=401%20Unauthorized。我用羽毛 cli 生成了一个新的应用程序。我究竟做错了什么?

配置/default.json

...
"oauth": {
  "redirect": "/",
  "twitch": {
    "key": ""*****************",",
    "secret": ""***************************************"",
    "scope": ["user:read:email"]
  },
  "github": {
    "key": "*****************",
    "secret": "***************************************"
  }
}...

标签: javascriptnode.jsoauthfeathersjs

解决方案


这是因为内置策略正在尝试获取用户配置文件,但它并未在标头中包含您的客户端 ID(请参阅Twitch API - 入门

要解决这个问题,您需要创建自己的策略来实现getProfile. 我使用了 feathersjs 食谱中的 Facebook 演示作为参考,可以在此处找到

这是我的实现:

./strategies/TwitchStrategy.ts

import { Params } from '@feathersjs/feathers'
import { AuthenticationRequest } from '@feathersjs/authentication'
import { OAuthStrategy, OAuthProfile } from '@feathersjs/authentication-oauth'
import axios from 'axios'
import { Application } from '../declarations'

export class TwitchStrategy extends OAuthStrategy {
    // we need a reference to the app instance
    app: Application = {} as Application

    // when the strategy is initialized this method is called with an app instance
    setApplication(appInstance: Application): void {
        this.app = appInstance
    }

    // this method is used to get the user profile after they authorize with the provider
    async getProfile(authResult: AuthenticationRequest, _params: Params) {
        const accessToken = authResult.access_token

        const { data } = await axios.get('https://api.twitch.tv/helix/users', {
            headers: {
                Authorization: `Bearer ${accessToken}`, //our users access token to look them up
                'Client-ID': this.app.get('authentication').oauth.twitch.key //we need to send the Client-ID
            },
            params: {
                fields: 'id,name,email'
            }
        })

        console.log(data)

        return data
    }

    async getEntityData(profile: OAuthProfile, existing: any, params: Params) {
        // `profile` is the data returned by getProfile
        const baseData = await super.getEntityData(profile, existing, params)

        return {
            ...baseData,
            email: profile.email
        }
    }
}

./authentication.ts

import { ServiceAddons } from '@feathersjs/feathers'
import { AuthenticationService, JWTStrategy } from '@feathersjs/authentication'
import { LocalStrategy } from '@feathersjs/authentication-local'
// import our strategy
import { TwitchStrategy } from './strategies/TwitchStrategy'
import { expressOauth } from '@feathersjs/authentication-oauth'
import { Application } from './declarations'

declare module './declarations' {
    interface ServiceTypes {
        authentication: AuthenticationService & ServiceAddons<any>
    }
}

export default function (app: Application): void {
    const authentication = new AuthenticationService(app)
    authentication.register('jwt', new JWTStrategy())
    // register our custom strategy
    authentication.register('twitch', new TwitchStrategy())
    authentication.register('local', new LocalStrategy())

    app.use('/authentication', authentication)
    app.configure(expressOauth())
}


推荐阅读