I'm trying to get user info from Twitch with React Native Expo, but it always returns 401 error.
I found that it correctly gets the OAuth token, but the problem occurs after it.
Here's my code:
WebBrowser.maybeCompleteAuthSession();
// Endpoint
const discovery = {
authorizationEndpoint: 'https://id.twitch.tv/oauth2/authorize',
tokenEndpoint: 'https://id.twitch.tv/oauth2/token',
revocationEndpoint: 'https://id.twitch.tv/oauth2/revoke',
};
// Login Screen
export function loginScreen({ navigation }) {
const [request, response, promptAsync] = useAuthRequest(
{
responseType: ResponseType.Token,
clientId: '(deleted)',
// For usage in managed apps using the proxy
redirectUri: makeRedirectUri({ useProxy: true }),
scopes: ['openid', 'user_read', 'user_subscriptions'],
},
discovery
);
React.useEffect(() => {
if (response?.type === 'success') {
fetch('https://api.twitch.tv/kraken/user', {
method: 'GET',
headers: {
'Accept': 'application/vnd.twitchtv.v5+json',
'Client-ID': '(deleted)',
'Authorization': 'OAuth ' + response.params
}
})
.then((data) => {
AsyncStorage.setItem('userData', JSON.stringify(data))
.then(() => console.log(JSON.stringify(data))) // console.log for testing
.then(() => navigation.navigate('Home'))
})
.catch((err) => alert(err))
}
}, [response]);
and I referred to this document for the authentication.
Twitch SignIn & get user information using Expo's expo-auth-session.
Step 1: Create an account and enable two-factor authentication on Twitch developer site.You will get a key.
Step 2: Install Expo's expo install expo-auth-session
Step 3: Add Scheme in App.json file
{
"expo": {
"scheme": "myapp"
}
}
In order to be able to deep link back into your app, you will need to set a scheme in your project app.config.js, or app.json, and then build your standalone app (it can't be updated with an OTA update). If you do not include a scheme, the authentication flow will complete but it will be unable to pass the information back into your application and the user will have to manually exit the authentication modal (resulting in a cancelled event).
Step 4:
import * as AuthSession from 'expo-auth-session';
// To fetch twitch user information
const getTwitchUserInformation = twitchToken => {
const url = 'https://api.twitch.tv/helix/users';
const header = {
Authorization: `Bearer ${twitchToken}`,
'Client-ID': SOCIAL_CONSTANTS.TWITCH_CLIENT_ID,
};
fetch(url, {
method: 'GET',
headers: header,
})
.then(response => response.json())
.then(response => {
const userResponse = response && response.data[0];
console.log(userResponse);
})
.catch(error => {
console.log(error);
});
};
const signInWithTwitch = async () => {
const redirectUrl = AuthSession.getRedirectUrl();
const authUrl = `https://id.twitch.tv/oauth2/authorize?client_id=${ENTER_CLIENT_ID_HERE}&redirect_uri=${redirectUrl}&response_type=token&scope=user:edit+user:read:email&force_verify=true`
const {type, params} = await AuthSession.startAsync({authUrl});
if (type === 'success') {
const {access_token, token_type} = params;
getTwitchUserInformation(access_token);
}
};
Link - https://medium.com/#rakesh.medpalli/twitch-signin-get-user-information-in-expo-using-expo-auth-session-a6a74812c096
Related
Here is my API request
const getData= async () => {
const cookie='workid_token=eyJra4rgrtF7SnlSETjIGrFYQy-P2SFmlE6A.Tw_rx0Ut_Kj9zLWRQ9X23w';
const qs = require('qs')
let body = qs.stringify({
gid: '1196'
})
await axios.post(
'https://www.google.com', body,
{
headers: {
'Cookie': cookie,
'Content-Type': 'application/x-www-form-urlencoded',
},
},
).then(response => {
console.log('data', response);
if (response.data.status === '1') {
const PHPSESSID = response.headers['set-cookie'];
var separatedvalue = PHPSESSID[0];
var sessid = separatedvalue.split('; path=/')[0];
}
}).catch(error => {
console.log(error);
});
};
I am implementing Axios API post request in my React Native application. When I run the application first time I am getting set-cookie value in response headers. If I kill the application and I open it second time I am not getting value in set-cookie. Also not receiving response from the API.
Note: I want to receive value from set-cookie all the times.
i have a react native app as the front end and am trying to implement login, on localhost i can login well but in production i get the error the GET method is not supported on this route supported methods POST. When i test the endpoint using thunder client from VS code it works but in my react native app i get the route not supported error.
react native code:
export const loginuser = (username,password) =>{
return async(dispatch)=>{
dispatch({type:REG_LOADER})
const headers = {
'Accept': 'application/json',
'Content-Type': 'application/json'
}
axios.post(ROOT_URL+"login/saler", {
username:username,
password:password,
},{headers:headers})
.then( async(response) => {
console.log(response.data)
dispatch({type:LOGIN_FAIL})
let user = response.data.customer
let status = response.data.status
if(status === "1"){
await AsyncStorage.setItem('userdata', JSON.stringify(user))
dispatch({type:LOGIN_SUCCESS,payload:user})
}else{
alert('Wrong phone number or password')
dispatch({type:LOGIN_FAIL})
}
})
.catch(function (error) {
alert(error.response.data.message)
dispatch({type:LOGIN_FAIL})
})
}
}
laravel route:
Route::group(['prefix' => 'v1', 'as' => 'api.', 'namespace' => 'Api\V1\Sales'], function () {
Route::post('/login/saler','Auth\LoginController#Login');
]);
enter code here
I have this authentication issue
The registration works perfectly and the servers take the registration data: User password email and number. After this step, I have OTP verification
I got the pin code and run the verification mutation.
On the verification, I got the error :
You are not authenticated
And the all process stops because I am not verified
Here is the code for the react-native part
const VERIFY = gql
mutation($token: String!, $kind: TokenKind!) {
verify(token: $token, kind: $kind)
}
const VerificationScreen: React.FC < any > = (props) => {
const token = (props as any).route.params.token;
const [loading, setLoading] = React.useState < boolean > (false)
const [pin, setPin] = useState < string > ('')
const [veryfy] = useMutation(VERIFY)
const verifyPin = () => {
if (!pin) {
alert('Please TYPE Valid PIN')
return;
}
//veryfy
setLoading(true);
veryfy({
variables: {
token: pin,
kind: 'PHONE'
}
}).then(({
data
}) => {
setLoading(false)
console.log(data);
if (data) {
props.navigation.navigate('Intro', {
token: token
});
}
}).catch((e) => {
setLoading(false)
console.log(e);
})
}
The below code is an example showing how you can use the Apollo middle-ware [1] and context [2] to add headers(auth) at runtime or testing.
First we create a middle-ware block, then an inner context block.
In the context block we can use the line below to add external parameters, this is to configure the request
const { isAuth, Authorization } = headers;
A boolean(Auth) can be set to allow a token to be embedded in a Authorization header, or an existing Authorization header can be passed in directly, this can be usefull for testing for example.
const getClient = () => {
// create link middleware see [1]
const authMiddleware = new ApolloLink((operation, forward) => {
// code block below assumes there exists an auth token in globals
// add headers with the client context [2]
operation.setContext(({ headers = {} }) => {
// auth header using global token as a bearer token
const authHeaders = {
Authorization: global.access_token
? `Bearer ${global.access_token}`
: "",
};
// here an Authorization header can be passed in thru the context,
// which can be useful, eg for testing
const { isAuth, Authorization } = headers;
// if we have an Auth.. header we can just add that and return
if (Authorization) {
return {
headers: { ...publicHeaders, ...{ Authorization } },
};
}
const header = isAuth
? { ...publicHeaders, ...authHeaders }
: publicHeaders;
return {
headers: header,
};
});
return forward(operation);
}); // end create middleware
// create the graphql endpoint [1]
const httpLink = new HttpLink({ uri: '/graphql' });
// create client with the middleware and return the client
// code block below assumes there exists a globalCache
return new ApolloClient({
cache: globalCache,
link: concat(authMiddleware, httpLink),
});
}
use
// add/configure the appropriate headers in the context block
// for the client
client
.mutate({
mutation: <some mutation>,
variables: <some variables>,
context: {
headers: {
isAuth: false, // or true for authenticated operation
},
},
})
.then((result) => ....)
.catch((err) => {
console.log(....);
});
use in a hook
const [runMutation, { data }] =
useMutation(<gql>, {
context: {
headers: { isAuth: true },
variables: <some vars>,
onCompleted: (data) => callback(data),
onError: (error) => console.error("Error ", error),
},
});
links
1 middleware
2 context
I have used the Vue-Authenticate plugin for the social login and this is my configuration for the Github Login
providers: {
github: {
clientId: 'my Id',
redirectUri: 'https://' + process.env.PROJECT_DOMAIN,
responseType: 'token',
authorizationEndpoint: 'https://github.com/login/oauth/authorize',
},
},
And in the method through which is calling the method after authentication is
authenticate(provider) {
const this_ = this
this.$auth.authenticate(provider).then(function () {
const token = this_.$auth.getToken()
if (provider === 'github') {
const options = {
headers: {
Authorization: 'token ' + token,
},
}
this_.$http
.post('https://api.github.com/user', options)
.then(function (response) {
if (response.status === 200) {
const { email, name, picture } = response.data
const data = {
email,
name,
image: picture.data.url,
}
this_.createOAuth2User(data, provider)
}
})
.catch((error) => {
console.log(error)
})
}
})
},
I am able to receive an access token after successful authentication but when I try to use that token to access the user details and hit the https://api.github.com/user API I am getting 401 error. So is there something I am missing while authentication with github?
I am not able to access the themes.json of my development store using shopify api and nodejs.
Here is what I am doing:
app.get('/shopify/examplePage', (req, res) => {
const { shop, hmac, code, state } = req.query;
const stateCookie = cookie.parse(req.headers.cookie).state;
// Verifying Cookie
if (state !== stateCookie) {
return res.status(403).send('Request origin cannot be verified');
}
// Verifying Hmac
if (shop && hmac && code) {
const map = Object.assign({}, req.query);
delete map['hmac'];
const message = querystring.stringify(map);
const generatedHash = crypto
.createHmac('sha256', apiSecret)
.update(message)
.digest('hex');
if(generatedHash !== hmac){
return res.status(400).send('HMAC verification failed');
}
// Appending Access Token to the shop Url
const accessTokenRequestUrl = 'https://' + shop + '/admin/oauth/access_token';
const accessTokenPayload = {
client_id: apiKey,
client_secret: apiSecret,
code
};
// Making an API Request And getting an API response
request.post(accessTokenRequestUrl, {json: accessTokenPayload })
// Promise for Access Token Response
.then((accessTokenResponse) => {
const accessToken = accessTokenResponse.access_token;
// Request URL for Products
const apiRequestUrl = 'https://' + shop + '/admin/api/2019-04/themes.json'
console.log(apiRequestUrl);
const apiRequestHeader = {
'X-Shopify-Access-Token': accessToken
};
request.get(apiRequestUrl, { headers: apiRequestHeader })
.then((apiResponse) => {
let example = JSON.parse(apiResponse);
res.send(example);
// End API Response
res.end(apiResponse)
}).catch((error) => {
res.status(error.statusCode).send(error.error.error_descripton)
});
}).catch((error) => {
res.status(error.statusCode).send(error.error.error_descripton)
})
} else {
res.status(400).send('Required parameters missing');
}
});
There is this error showing that the access to {ngrok}.ngrok.io was denied while I can access product.json & shop.json with the help of same code
Denied means your API key doesn’t have access. If this is a public app you need to add read_themes to your scopes. If it is a private app you need to go to the app setup and add theme access.