diff --git a/README.md b/README.md
index 1da971f..452fd73 100644
--- a/README.md
+++ b/README.md
@@ -52,6 +52,28 @@ const SomeOtherComponent = () => (
This is some other component
)
const ProtectedComponent = authenticated()(() => ())
```
+Instead of the higher-order function the hook `useAuthentication` can be used for the same purpose:
+
+```js
+import { useAuthentication } from 'react-u5auth'
+
+const SomeComponent = () => (
+ Some component that needs an authenticated user...
+)
+
+const ProtectedComponent = () => {
+ const { authenticated } = useAuthentication()
+
+ if (!authenticated) {
+ // This will appear only for a short time before the
+ // redirect to the auth provider URL kicks in.
+ return Logging in...
+ } else {
+ return
+ }
+}
+```
+
## Using the `access_token`
A protected component isn't too valuable on its own, you may need an access
@@ -66,6 +88,13 @@ const token = getLocalToken()
...
```
+The `useAuthentication` hook also returns the token:
+
+```js
+const { authenticated, token } = useAuthentication()
+```
+
+
Please note: There is something fishy here about the `access_token`
being kept in global state. See
[this issue](https://github.com/Uber5/react-u5auth/issues/3).
diff --git a/src/authenticated.js b/src/authenticated.js
index 6d1d618..582ed7a 100644
--- a/src/authenticated.js
+++ b/src/authenticated.js
@@ -1,24 +1,9 @@
import React from 'react'
import { getLocalToken } from './local-token'
-import contextTypes from './context-types'
-
-export function hashed(o) {
- return Object
- .getOwnPropertyNames(o)
- .map(prop => `${ prop }=${ encodeURIComponent(o[prop]) }`)
- .join('&')
-}
+import AuthContextType from './context-types'
+import { authorize } from './lib/utils'
export const authenticated = () => Component => {
- function authorize(provider, clientId) {
- const query = {
- client_id: clientId,
- response_type: 'token',
- redirect_uri: window.location
- }
- const url = `${ provider }/authorize?${ hashed(query) }`
- window.location.replace(url)
- }
class Authed extends React.Component {
render() {
const token = getLocalToken()
@@ -31,6 +16,6 @@ export const authenticated = () => Component => {
}
}
}
- Authed.contextTypes = contextTypes
+ Authed.contextType = AuthContextType
return Authed
}
diff --git a/src/components/auth-context.js b/src/components/auth-context.js
index 5f2a8c6..4f395d9 100644
--- a/src/components/auth-context.js
+++ b/src/components/auth-context.js
@@ -1,5 +1,6 @@
import React from 'react'
-import contextTypes from '../context-types'
+import AuthContextType from '../context-types'
+import PropTypes from 'prop-types'
import { getHashValues } from '../lib/utils'
import TokenManager from './token-manager'
@@ -40,11 +41,6 @@ class Debug extends React.Component {
}
export class AuthContext extends React.Component {
- getChildContext() {
- const { provider, clientId, loggingInIndicator } = this.props
- return { provider, clientId, loggingInIndicator }
- }
-
isDebugEnabled = () => {
return !!(localStorage.getItem('debug') || '').match(/react-u5auth/)
}
@@ -59,18 +55,23 @@ export class AuthContext extends React.Component {
console.log('react-u5auth, debug', debug)
return (
-
{
- this.setState({ token })
- onTokenUpdate && onTokenUpdate(token)
- }}
- />
- { debug && }
- { showChildren && this.props.children }
+
+ {
+ this.setState({ token })
+ onTokenUpdate && onTokenUpdate(token)
+ }}
+ />
+ { debug && }
+ { showChildren && this.props.children }
+
)
}
}
-AuthContext.propTypes = contextTypes
-AuthContext.childContextTypes = contextTypes
+AuthContext.propTypes = {
+ provider: PropTypes.string.isRequired,
+ clientId: PropTypes.string.isRequired,
+ loggingInIndicator: PropTypes.element
+}
diff --git a/src/components/token-manager.js b/src/components/token-manager.js
index a8f67cc..2b90bd6 100644
--- a/src/components/token-manager.js
+++ b/src/components/token-manager.js
@@ -1,7 +1,7 @@
import React from 'react'
import { setLocalToken, getLocalToken, getLocalExpiresAt } from '../local-token'
-import contextTypes from '../context-types'
-import { hashed } from '../authenticated'
+import AuthContextType from '../context-types'
+import { hashed } from '../lib/utils'
import { getHashValues } from '../lib/utils'
class TokenManager extends React.Component {
@@ -169,6 +169,6 @@ class TokenManager extends React.Component {
}
}
-TokenManager.contextTypes = contextTypes
+TokenManager.contextType = AuthContextType
export default TokenManager
diff --git a/src/context-types.js b/src/context-types.js
index a39dd9f..b3edf67 100644
--- a/src/context-types.js
+++ b/src/context-types.js
@@ -1,9 +1,5 @@
-import PropTypes from 'prop-types'
+import { createContext } from 'react'
-const contextTypes = {
- provider: PropTypes.string.isRequired,
- clientId: PropTypes.string.isRequired,
- loggingInIndicator: PropTypes.element
-}
+const AuthContextType = createContext()
-export default contextTypes
+export default AuthContextType
diff --git a/src/index.js b/src/index.js
index d66f8df..1b3a24d 100644
--- a/src/index.js
+++ b/src/index.js
@@ -1,5 +1,6 @@
import { AuthContext } from './components/auth-context'
import { authenticated } from './authenticated'
+import { useAuthentication } from './useAuthentication'
import { getLocalToken } from './local-token'
-export { AuthContext, authenticated, getLocalToken }
+export { AuthContext, authenticated, useAuthentication, getLocalToken }
diff --git a/src/lib/utils.js b/src/lib/utils.js
index 8162bf2..b459306 100644
--- a/src/lib/utils.js
+++ b/src/lib/utils.js
@@ -1,4 +1,16 @@
+export const hashed = o => Object.getOwnPropertyNames(o)
+ .map(prop => `${ prop }=${ encodeURIComponent(o[prop]) }`)
+ .join('&')
+export const authorize = (provider, clientId) => {
+ const query = {
+ client_id: clientId,
+ response_type: 'token',
+ redirect_uri: window.location
+ }
+ const url = `${ provider }/authorize?${ hashed(query) }`
+ window.location.replace(url)
+}
export const getHashValues = () => {
const hash = window.location.hash
diff --git a/src/useAuthentication.js b/src/useAuthentication.js
new file mode 100644
index 0000000..cb1c38b
--- /dev/null
+++ b/src/useAuthentication.js
@@ -0,0 +1,16 @@
+import { useContext } from 'react'
+import { getLocalToken } from './local-token'
+import AuthContextType from './context-types'
+import { authorize } from './lib/utils'
+
+export function useAuthentication() {
+ const token = getLocalToken()
+ const { clientId, provider } = useContext(AuthContextType)
+
+ if (!token) {
+ authorize(provider, clientId)
+ return { authenticated: false }
+ } else {
+ return { authenticated: true, token }
+ }
+}