-
Notifications
You must be signed in to change notification settings - Fork 131
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Showing
275 changed files
with
26,973 additions
and
2,232 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
[*.cs] | ||
|
||
# CS1591: Missing XML comment for publicly visible type or member | ||
dotnet_diagnostic.CS1591.severity = silent |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
name: build | ||
|
||
on: | ||
push: | ||
branches: '**' | ||
tags: 'v*.*.*' | ||
pull_request: | ||
|
||
jobs: | ||
build: | ||
runs-on: windows-latest | ||
steps: | ||
- uses: actions/checkout@v3 | ||
- name: Setup .NET Core | ||
uses: actions/setup-dotnet@v3 | ||
with: | ||
dotnet-version: 6 | ||
- name: Setup MSBuild | ||
uses: microsoft/[email protected] | ||
- name: Build | ||
run: .\build\build-libs.ps1 | ||
env: | ||
DOTNET_CLI_TELEMETRY_OPTOUT: 1 | ||
- name: Run Tests | ||
env: | ||
FIREBASE_AUTH_TEST_API_KEY: ${{ secrets.FIREBASE_AUTH_TEST_API_KEY }} | ||
FIREBASE_AUTH_TEST_DOMAIN: ${{ secrets.FIREBASE_AUTH_TEST_DOMAIN }} | ||
run: .\build\run-tests.ps1 | ||
pack: | ||
runs-on: windows-latest | ||
needs: build | ||
if: github.event_name == 'push' | ||
steps: | ||
- uses: actions/checkout@v3 | ||
- name: Setup .NET Core | ||
uses: actions/setup-dotnet@v3 | ||
with: | ||
dotnet-version: 6 | ||
- name: Setup MSBuild | ||
uses: microsoft/[email protected] | ||
- name: Pack preview | ||
if: startsWith(github.ref, 'refs/tags/') == false | ||
run: .\build\run-pack.ps1 -preview | ||
env: | ||
DOTNET_CLI_TELEMETRY_OPTOUT: 1 | ||
- name: Pack from tag | ||
if: startsWith(github.ref, 'refs/tags/') | ||
run: .\build\run-pack.ps1 | ||
env: | ||
DOTNET_CLI_TELEMETRY_OPTOUT: 1 | ||
- uses: actions/upload-artifact@v3 | ||
with: | ||
name: artifacts | ||
path: ./artifacts | ||
publish: | ||
runs-on: ubuntu-latest | ||
needs: pack | ||
if: github.event_name == 'push' | ||
steps: | ||
- name: Setup .NET Core | ||
uses: actions/setup-dotnet@v3 | ||
with: | ||
dotnet-version: 6 | ||
- uses: actions/download-artifact@v3 | ||
with: | ||
name: artifacts | ||
path: ./artifacts | ||
- name: Publish to Feedz.io | ||
if: startsWith(github.ref, 'refs/tags/') == false | ||
run: dotnet nuget push ./artifacts/**/*.nupkg --source https://f.feedz.io/step-up-labs/firebase/nuget/index.json --api-key ${{secrets.FEEDZ_TOKEN}} | ||
- name: Publish to Nuget.org | ||
if: startsWith(github.ref, 'refs/tags/') | ||
run: dotnet nuget push ./artifacts/**/*.nupkg --source https://api.nuget.org/v3/index.json --api-key ${{secrets.NUGET_TOKEN}} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,59 +1,223 @@ | ||
# FirebaseAuthentication.net | ||
[![AppVeyor Build status](https://ci.appveyor.com/api/projects/status/rwmdgqcb7is2clqp?svg=true)](https://ci.appveyor.com/project/bezysoftware/firebase-authentication-dotnet) | ||
[![build](https://github.com/step-up-labs/firebase-authentication-dotnet/workflows/build/badge.svg)](https://github.com/step-up-labs/firebase-authentication-dotnet/actions) | ||
[![latest version](https://img.shields.io/nuget/v/FirebaseAuthentication.net)](https://www.nuget.org/packages/FirebaseAuthentication.net) | ||
[![feedz.io](https://img.shields.io/badge/endpoint.svg?url=https%3A%2F%2Ff.feedz.io%2Fstep-up-labs%2Ffirebase%2Fshield%2FFirebaseAuthentication.net%2Flatest)](https://f.feedz.io/step-up-labs/firebase/packages/FirebaseAuthentication.net/latest/download) | ||
|
||
❗ New version of this library with **FirebaseUI** support is being developed in [v4 branch](https://github.com/step-up-labs/firebase-authentication-dotnet/tree/feature/v4) ❗ | ||
FirebaseAuthentication.net is an unofficial C# implementation of [Firebase Authentication](https://firebase.google.com/docs/auth) | ||
and [FirebaseUI](https://firebase.google.com/docs/auth). | ||
|
||
Firebase authentication library. It can generate Firebase auth token based on given OAuth token (issued by Google, Facebook...). This Firebase token can then be used with REST queries against Firebase Database endpoints. See [FirebaseDatabase.net](https://github.com/step-up-labs/firebase-database-dotnet) for a C# library wrapping the Firebase Database REST queries. | ||
The libraries provide a drop-in auth solution that handles the flows for signing in users with email addresses and passwords, Identity Provider Sign In including Google, Facebook, GitHub, Twitter, Apple, Microsoft and anonymous sign-in. | ||
|
||
The solution consists of 4 libraries - a base one and 3 platform specific ones: | ||
* FirebaseAuthentication<strong>.net</strong> targets [.NET Standard 2.0](https://github.com/dotnet/standard/blob/master/docs/versions.md) | ||
* FirebaseAuthentication<strong>.WPF</strong> targets [WPF on .NET 6](https://github.com/dotnet/wpf) | ||
* FirebaseAuthentication<strong>.UWP</strong> targets [UWP with min version 19041](https://docs.microsoft.com/en-us/windows/uwp/updates-and-versions/choose-a-uwp-version) | ||
* FirebaseAuthentication<strong>.Xamarin</strong> targets Xamarin.Forms (*TODO*) | ||
|
||
## Installation | ||
```csharp | ||
// Install release version | ||
Install-Package FirebaseAuthentication.net | ||
|
||
Either via Visual Studio [Nuget](https://www.nuget.org/packages/FirebaseAuthentication.net) package manager, or from command line: | ||
|
||
```powershell | ||
# base package | ||
dotnet add package FirebaseAuthentication.net | ||
# Platform specific FirebaseUI (has dependency on base package) | ||
dotnet add package FirebaseAuthentication.WPF | ||
dotnet add package FirebaseAuthentication.UWP | ||
dotnet add package FirebaseAuthentication.Xamarin | ||
``` | ||
|
||
## Supported frameworks | ||
* .NET Standard 1.1 - see https://github.com/dotnet/standard/blob/master/docs/versions.md for compatibility matrix | ||
Use the `--version` option to specify a [preview version](https://www.nuget.org/packages/FirebaseAuthentication.net/absoluteLatest) to install. | ||
|
||
## Supported scenarios | ||
* Login with Google / Facebook / Github / Twitter OAuth tokens | ||
* Anonymous login | ||
* Login with email + password | ||
* Create new user with email + password | ||
* Send a password reset email | ||
* Link two accounts together | ||
Daily preview builds are also available on [feedz.io](https://feedz.io). Just add the following Package Source to your Visual Studio: | ||
|
||
``` | ||
https://f.feedz.io/step-up-labs/firebase/nuget/index.json | ||
``` | ||
|
||
## Usage | ||
|
||
In general the terminology and API naming conventions try to follow the official JavaScript implementation, adjusting it to fit the .NET conventions. | ||
E.g. `signInWithCredential` is called `SignInWithCredentialAsync` because it is meant to be `await`ed, but otherwise the terminology should be mostly the same. | ||
|
||
|
||
### Samples | ||
There are currently 3 sample projects in the [samples folder](/samples/): | ||
|
||
* .NET Core Console application (uses only the base library, no UI) | ||
* WPF sample with UI | ||
* UWP sample with UI | ||
|
||
Feel free to clone the repo and check them out, just don't forget to add your custom API keys and other setup (typically in `Program.cs` or `App.xaml.cs`). | ||
|
||
![](art/SampleWPF.png) | ||
|
||
### Setup | ||
|
||
For general Firebase setup, refer to the [official documentation](https://firebase.google.com/docs/auth) which discusses the general concepts and individual providers in detail. | ||
You might also want to check out the first two steps in this [web documentation](https://firebase.google.com/docs/web/setup). | ||
Notice that Firebase doesn't officially support Windows as a platform so you will have to register your application as a web app in [Firebase Console](https://console.firebase.google.com/). | ||
|
||
### FirebaseAuthentication.net | ||
|
||
The base library gives you the same features as the official *Firebase SDK Authentication*, that is without any UI. Your entrypoint is the `FirebaseAuthClient`. | ||
|
||
```csharp | ||
var authProvider = new FirebaseAuthProvider(new FirebaseConfig(FirebaseApiKey)); | ||
var facebookAccessToken = "<login with facebook and get oauth access token>"; | ||
|
||
var auth = await authProvider.SignInWithOAuthAsync(FirebaseAuthType.Facebook, facebookAccessToken); | ||
|
||
var firebase = new FirebaseClient( | ||
"https://dinosaur-facts.firebaseio.com/", | ||
new FirebaseOptions | ||
{ | ||
AuthTokenAsyncFactory = () => Task.FromResult(auth.FirebaseToken) | ||
}); | ||
|
||
var dinos = await firebase | ||
.Child("dinosaurs") | ||
.OnceAsync<Dinosaur>(); | ||
|
||
foreach (var dino in dinos) | ||
// main namespaces | ||
using Firebase.Auth; | ||
using Firebase.Auth.Providers; | ||
using Firebase.Auth.Repository; | ||
|
||
// Configure... | ||
var config = new FirebaseAuthConfig | ||
{ | ||
Console.WriteLine($"{dino.Key} is {dino.Object.Height}m high."); | ||
} | ||
ApiKey = "<API KEY>", | ||
AuthDomain = "<DOMAIN>.firebaseapp.com", | ||
Providers = new FirebaseAuthProvider[] | ||
{ | ||
// Add and configure individual providers | ||
new GoogleProvider().AddScopes("email"), | ||
new EmailProvider() | ||
// ... | ||
}, | ||
// WPF: | ||
UserRepository = new FileUserRepository("FirebaseSample") // persist data into %AppData%\FirebaseSample | ||
// UWP: | ||
UserRepository = new StorageRepository() // persist data into ApplicationDataContainer | ||
}; | ||
|
||
// ...and create your FirebaseAuthClient | ||
var client = new FirebaseAuthClient(config); | ||
``` | ||
|
||
## Facebook setup | ||
Notice the `UserRepository`. This tells `FirebaseAuthClient` where to store the user's credentials. | ||
By default the libraries use in-memory repository; to preserve user's credentials between application runs, use `FileUserRepository` (or your custom implementation of `IUserRepository`). | ||
|
||
Under [Facebook developers page for your app](https://developers.facebook.com/) make sure you have a similar setup: | ||
After you have your `client`, you can sign-in or sign-up the user with any of the configured providers. | ||
|
||
![Logo](/art/FacebookSetup.png) | ||
```csharp | ||
// anonymous sign in | ||
var user = await client.SignInAnonymouslyAsync(); | ||
|
||
// sign up or sign in with email and password | ||
var userCredential = await client.CreateUserWithEmailAndPasswordAsync("email", "pwd", "Display Name"); | ||
var userCredential = await client.SignInWithEmailAndPasswordAsync("email", "pwd"); | ||
|
||
// sign in via provider specific AuthCredential | ||
var credential = TwitterProvider.GetCredential("access_token", "oauth_token_secret"); | ||
var userCredential = await client.SignInWithCredentialAsync(credential); | ||
|
||
// sign in via web browser redirect - navigate to given uri, monitor a redirect to | ||
// your authdomain.firebaseapp.com/__/auth/handler | ||
// and return the whole redirect uri back to the client; | ||
// this method is actually used by FirebaseUI | ||
var userCredential = await client.SignInWithRedirectAsync(provider, async uri => | ||
{ | ||
return await OpenBrowserAndWaitForRedirectToAuthDomain(uri); | ||
}); | ||
``` | ||
|
||
As you can see the sign-in methods give you a `UserCredential` object, which contains an `AuthCredential` and a `User` objects. | ||
`User` holds details about a user as well as some useful methods, e.g. `GetIdTokenAsync()` to get a valid *IdToken* you can use as an access token to other Firebase API (e.g. Realtime Database). | ||
|
||
```csharp | ||
// user and auth properties | ||
var user = userCredential.User; | ||
var uid = user.Uid; | ||
var name = user.Info.DisplayName; // more properties are available in user.Info | ||
var refreshToken = user.Credential.RefreshToken; // more properties are available in user.Credential | ||
// user methods | ||
var token = await user.GetIdTokenAsync(); | ||
await user.DeleteAsync(); | ||
await user.ChangePasswordAsync("new_password"); | ||
await user.LinkWithCredentialAsync(authCredential); | ||
``` | ||
|
||
To sign out a user simply call | ||
```csharp | ||
client.SignOut(); | ||
``` | ||
|
||
### FirebaseUI | ||
|
||
The platform specific UI libraries use the `FirebaseAuthClient` under the hood, but need to be initilized via the static `Initialize` method of `FirebaseUI`: | ||
|
||
## Google setup | ||
```csharp | ||
// Initialize FirebaseUI during your application startup (e.g. App.xaml.cs) | ||
FirebaseUI.Initialize(new FirebaseUIConfig | ||
{ | ||
ApiKey = "<API KEY>", | ||
AuthDomain = "<DOMAIN>.firebaseapp.com", | ||
Providers = new FirebaseAuthProvider[] | ||
{ | ||
new GoogleProvider().AddScopes("email"), | ||
new EmailProvider() | ||
// and others | ||
}, | ||
PrivacyPolicyUrl = "<PP URL>", | ||
TermsOfServiceUrl = "<TOS URL>", | ||
IsAnonymousAllowed = true, | ||
UserRepository = new FileUserRepository("FirebaseSample") // persist data into %AppData%\FirebaseSample | ||
}); | ||
``` | ||
|
||
Notice the `UserRepository`. This tells FirebaseUI where to store the user's credentials. | ||
By default the libraries use in-memory repository; to preserve user's credentials between application runs, use `FileUserRepository` (or your custom implementation of `IUserRepository`). | ||
|
||
FirebaseUI comes with `FirebaseUIControl` you can use in your xaml as follows: | ||
|
||
```xml | ||
<!--WPF Sample--> | ||
<Page x:Class="Firebase.Auth.Wpf.Sample.LoginPage" | ||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" | ||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" | ||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" | ||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" | ||
xmlns:firebase="clr-namespace:Firebase.Auth.UI;assembly=Firebase.Auth.UI.WPF" | ||
mc:Ignorable="d" | ||
d:DesignHeight="450" | ||
d:DesignWidth="800"> | ||
|
||
<Grid> | ||
<firebase:FirebaseUIControl> | ||
<firebase:FirebaseUIControl.Header> | ||
<!--Custom content shown above the provider buttons--> | ||
<Image | ||
Height="150" | ||
Source="/Assets/firebase.png" | ||
/> | ||
</firebase:FirebaseUIControl.Header> | ||
</firebase:FirebaseUIControl> | ||
</Grid> | ||
</Page> | ||
``` | ||
|
||
In the [developer console](https://console.developers.google.com/apis/credentials) make sure you have an OAuth client (set it either as iOS or Android app, that should work). | ||
Toggling the visibility of this UI control is up to you, depending on your business logic. | ||
E.g. you could show it as a popup, or a `Page` inside a `Frame` etc. | ||
You would typically want to toggle the control's visibility in response to the `AuthStateChanged` event: | ||
|
||
```csharp | ||
// subscribe to auth state changes | ||
FirebaseUI.Instance.Client.AuthStateChanged += this.AuthStateChanged; | ||
|
||
private void AuthStateChanged(object sender, UserEventArgs e) | ||
{ | ||
// the callback is not guaranteed to be on UI thread | ||
Application.Current.Dispatcher.Invoke(() => | ||
{ | ||
if (e.User == null) | ||
{ | ||
// no user is signed in (first run of the app, user signed out..), show login UI | ||
this.ShowLoginUI(); | ||
} | ||
else if (this.loginUIShowing) | ||
{ | ||
// user signed in (or was already signed in), hide the login UI | ||
// this event can be raised multiple times (e.g. when access token gets refreshed), you need to be ready for that | ||
this.HideLoginUI(); | ||
} | ||
}); | ||
} | ||
``` |
Binary file not shown.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
dotnet build --configuration release .\src\Auth\Auth.csproj | ||
dotnet build --configuration release .\src\Auth.UI\Auth.UI.csproj | ||
dotnet build --configuration release .\src\Auth.UI.WPF\Auth.UI.WPF.csproj | ||
msbuild /restore /p:Configuration=Release .\src\Auth.UI.UWP\Auth.UI.UWP.csproj |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
dotnet build --configuration release .\samples\Console\Auth.Console.Sample.csproj | ||
dotnet build --configuration release .\samples\WPF\Auth.WPF.Sample.csproj | ||
msbuild /restore /p:Configuration=Debug .\samples\UWP\Auth.UWP.Sample.csproj |
Oops, something went wrong.