microsoftgraph / msgraph-sample-phpapp Goto Github PK
View Code? Open in Web Editor NEWThis sample demonstrates how to use the Microsoft Graph .NET SDK to access data in Office 365 from PHP web apps.
License: MIT License
This sample demonstrates how to use the Microsoft Graph .NET SDK to access data in Office 365 from PHP web apps.
License: MIT License
Composer cannot install the project, because of the invalid microsoft-graph version. This is located in the composer.json file https://github.com/microsoftgraph/msgraph-training-phpapp/blob/68bfcb823cf5b8c74e3c9ed47c630ccbf35bbbe4/demo/graph-tutorial/composer.json#L18
Steps to reproduce the behavior:
Following the quick start guide for PHP: https://developer.microsoft.com/en-us/graph/quick-start
The composer install process should complete package installation without error.
If applicable, add screenshots to help explain your problem.
microsoft/microsoft-graph: "^1.49"
https://github.com/microsoftgraph/msgraph-sdk-php
The bug was corrected using a valid version number, "^1.49"
Actually, the issue is, that I am NOT getting the code!
After successfully generating the app secret and entering it in step 2 here
Microsoft Graph Quick Start
I press the button below step 3:
which produces an error 404: Not Found.
see above
I expected to get the quick start code!
Hi
Using your code:-
https://docs.microsoft.com/en-us/graph/tutorials/php?tutorial-step=1
I have managed to create an event in my outlook calendar, for identification purposes, I place our appointment_id into transactionId - I don't save the ID returned by your API - firstly - should I?
Secondly, does this plugin allow the following:-
Update an existing event and if so, is there an example or documentation?
Delete an existing event and if so, is there an example or documentation?
Thirdly, do you have, or is there, any examples of working with recurring events, as above really, to be able to create, update, delete the series?
If this is the wrong place to ask, can you please provide a link to where is best to ask the above?
Kind regards in advance.
Carl.
Hi
In my Laravel system, we have a diary and can create single item diary appointments and recurring. When I edit an appointment that is a single item, the code works, when I then edit a recurring sequence, the update fails.
The code to do the update is:-
$response = $graph->createRequest('PATCH', '/me/events/' . $existing_appointment->MicrosoftID)
->attachBody($newEvent)
->setReturnType(Model\Event::class)
->execute();
The exception error that is displayed on screen is
Client error: `PATCH https://graph.microsoft.com/v1.0/me/events/{id}` resulted in a `404 Not Found` response: ◀
{"error":{"code":"ErrorItemNotFound","message":"The specified object was not found in the store.","innerError":{"date":"2021-11-16T09:51:35","request-id":"{request_id}","client-request-id":"{client_request_id}"}}} ◀
I've removed the id's for security purposes.
Also, i've double checked the ID (by pulling the events from the calendar - using your test code) and the ID is exact!
Any idea why this error occurs?
Also, I've tried to DELETE the event and re-create a new one but the delete fails with the not found in store. BUT, I know it exists as my laptop displays it!
Thanks for any help in fixing this issue.
Regards
Carl.
Hi sir
Hope you are doing well.I read the documentation : https://docs.microsoft.com/en-us/graph/tutorials/php
and implement the PHP apps with Microsoft Graph.
Everything is right but a issue come when i send the get request using graph then it returned Microsoft\Graph\Http\GraphResponse Object when i use the method getDisplayName() it return Call to undefined method Microsoft\Graph\Http\GraphResponse::getDisplayName().
I just need to get the name and email.
So kindly help me in this regard
I shall be very thankful to you.Please🙏
The exeption rises following step 4 of the tutorial: Get a calendar view, paragraph "Display the results".
InvalidArgumentException
Action App\Http\Controllers\CalendarController@getNewEventForm not defined. (View: /path_to_project_dir/resources/views/calendar.blade.php)
It is caused by this line (in my case line 6) in the resources/views/calendar.blade.php
source file.
<a class="btn btn-light btn-sm mb-3" href={{action('CalendarController@getNewEventForm')}}>New event</a>
Follow the tutorial until "Display the results" paragraph, included.
Refreshing the browser view/tab should display calendar events list instead of the exception.
The route Route::get('/calendar/new', 'CalendarController@getNewEventForm');
should be added before "Display the results" paragraph and not in the next step (step 5) of the tutorial.
"require": {
"php": "^7.3|^8.0",
"fideloper/proxy": "^4.4",
"fruitcake/laravel-cors": "^2.0",
"laravel/framework": "^8.12",
"laravel/tinker": "^2.5",
"league/oauth2-client": "^2.6",
"microsoft/microsoft-graph": "^1.25"
},
"require-dev": {
"facade/ignition": "^2.5",
"fakerphp/faker": "^1.9.1",
"laravel/sail": "^0.0.5",
"mockery/mockery": "^1.4.2",
"nunomaduro/collision": "^5.0",
"phpunit/phpunit": "^9.3.3"
},
Hey,
First of all, thanks for this guide which is really a great way to start with ms graph
Is there a version of it to integrate the functionality of a no-user connection ?
Thank you
Ive granted the app all needed permission, but i still get the message that i should login as an admin.
Is there a way to prevent this?
I met issues with the signin method. It worked well at th beginning and then stopped working (TOO_MANY_REDIRECTS)....
By investigation, I realised that the array given for initializing the OAuth client was empty. Actually, the .env keys where not read. This is a problem that I already met in other Laravel projects : env(...) function does not work after the config is cached.
This can be solved declaring these variables in the config/app.php file and then calling them in the controller with the global config helper.
In our case, add these lines in the config/app.php file :
/*
|--------------------------------------------------------------------------
| Microsoft OAUTH
|--------------------------------------------------------------------------
*/
'clientId' => env('OAUTH_APP_ID'),
'clientSecret' => env('OAUTH_APP_PASSWORD'),
'redirectUri' => env('OAUTH_REDIRECT_URI'),
'urlAuthorize' => env('OAUTH_AUTHORITY').env('OAUTH_AUTHORIZE_ENDPOINT'),
'urlAccessToken' => env('OAUTH_AUTHORITY').env('OAUTH_TOKEN_ENDPOINT'),
'scopes' => env('OAUTH_SCOPES'),
In the AuthController.php file, initialize the OAuth client this way :
// Initialize the OAuth client
$oauthClient = new \League\OAuth2\Client\Provider\GenericProvider([
'clientId' => config('app.clientId'),
'clientSecret' => config('app.clientSecret'),
'redirectUri' => config('app.redirectUri'),
'urlAuthorize' => config('app.urlAuthorize'),
'urlAccessToken' => config('app.urlAccessToken'),
'urlResourceOwnerDetails' => '',
'scopes' => config('app.scopes'),
]);
Then, run the command php artisan config:clear
I hope this can help
AADSTS50194: Application '3b79e557-4d51-4b78-a1b0-82f9dd'(Testing for mail read) is not configured as a multi-tenant application. Usage of the /common endpoint is not supported for such applications created after '10/15/2018'. Use a tenant-specific endpoint or configure the application to be multi-tenant.
When we click on sign out, its not clear access token, and when we again sign in its not ask showing credentials window and direct giving login to session user.
I have also calling session flush fucntion from signout function.
like -
Session::forget('_token');
session()->forget('_token');
but its not working.
Steps to reproduce the behavior:
Sign out must clear session data but its skip token in session as it is.
If applicable, add screenshots to help explain your problem.
Add any other context about the problem here.
League\OAuth2\Client\Provider\Exception\IdentityProviderException
invalid_client
http://localhost:8000/callback?code=M.R3_BAY.4b726340-f363-8457-798b-3b54b282f833&state=6e71605213561ac6f226ac06d5e73219
Followed the simple steps as outlined. Tried clearing config and app cache.
Getting the same issue as #53 and #6
OR I'm just getting the default home page after the callback.
Steps to reproduce the behavior:
Follow the steps as outlined in the https://developer.microsoft.com/graph/quick-start
I don't know, never got to that point - I suppose I should see a UI showing my calendar.
If applicable, add screenshots to help explain your problem.
Laravel version 7.30.4
PHP version 7.3.24
I am following the tutorial and found that the "No access token has been provided." error from Laravel in the Calendar chapter.
The Calendar controller will get the access token and set it in the graph api.
// Get the access token from the cache
$tokenCache = new TokenCache();
$accessToken = $tokenCache->getAccessToken();
// Create a Graph client
$graph = new Graph();
$graph->setAccessToken($accessToken);
However, if the session never expired and never refresh the token, the session('refreshToken')
valuw will be null and the function getAccessToken()
returning the empty string to the CalendarController.
public function getAccessToken() {
// Check if tokens exist
if (empty(session('accessToken')) ||
empty(session('refreshToken')) ||
empty(session('tokenExpires'))) {
return '';
}
Is this a bug or I missed some steps?
Hi,
I tried replicating the project on Laravel 10 after generating the key via artisan when I click on sign in I get: 127.0.0.1 redirected you too many times.(this error). After clearing the cache still the same error persist. Can you give guidance on how can I resolve this.
Is there a way to return the raw JSON instead of converting it to an object?
Once converted to a specific object you lose the $count result.
when run composer install
In PackageManifest.php line 131: Undefined index: name
I use PHP 7.4 with laragon
fixed with composer self-update --1
Hi
When I create an event in the calendar (an appointment) and am creating it for another office 365 user, how to I set the attendees so that me (the creator) either doesn't see it in my calendar OR make me an optional attendee?
I've tried
$attendees[] = [
'emailAddress' => [
'address' => $staffOrganiser->StaffEmail,
],
'type' => 'optional',
];
$staffAttendee = \UserHelpers::getStaffById($app_user->StaffID);
$attendees[] = [
'emailAddress' => [
'address' => $staffAttendee->StaffEmail,
],
'type' => 'required',
];
I've currently just set the attendees to
$staffAttendee = \UserHelpers::getStaffById($app_user->StaffID);
$attendees[] = [
'emailAddress' => [
'address' => $staffAttendee->StaffEmail,
],
'type' => 'required',
];
I'd prefer NOT to show in the organisers calendar if the event is for another person!
Thanks for any and all help in advance
Carl.
Hi,
I just tried to implement your tutorial but it seems that I get an error "invalid_client".
`:\xampp\htdocs\vendor\league\oauth2-client\src\Provider\GenericProvider.php
protected function getScopeSeparator()
{
return $this->scopeSeparator ?: parent::getScopeSeparator();
}
/**
* @inheritdoc
*/
protected function checkResponse(ResponseInterface $response, $data)
{
if (!empty($data[$this->responseError])) {
$error = $data[$this->responseError];
if (!is_string($error)) {
$error = var_export($error, true);
}
$code = $this->responseCode && !empty($data[$this->responseCode])? $data[$this->responseCode] : 0;
if (!is_int($code)) {
$code = intval($code);
}
**throw new IdentityProviderException($error, $code, $data);**
}
}
/**
* @inheritdoc
*/
protected function createResourceOwner(array $response, AccessToken $token)
{
return new GenericResourceOwner($response, $this->responseResourceOwnerId);
}
}
`
I have a token generated for oAuth and added calendars.readwrite to my scope in my constants and scope for the web app and calendars works in my development but when i pushed it to productions gives me a 401.
my oauth:
$provider = new \League\OAuth2\Client\Provider\GenericProvider([
'clientId' => OAuthConstants::CLIENT_ID,
'clientSecret' => OAuthConstants::CLIENT_SECRET,
'redirectUri' => OAuthConstants::REDIRECT_URI,
'urlAuthorize' => OAuthConstants::AUTHORITY_URL . OAuthConstants::AUTHORIZE_ENDPOINT,
'urlAccessToken' => OAuthConstants::AUTHORITY_URL . OAuthConstants::TOKEN_ENDPOINT,
'urlResourceOwnerDetails' => '',
'scopes' => OAuthConstants::SCOPES
]);
if ($_SERVER['REQUEST_METHOD'] === 'GET' && !isset($_GET['code'])) {
$authorizationUrl = $provider->getAuthorizationUrl();
// The OAuth library automaticaly generates a state value that we can
// validate later. We just save it for now.
$_SESSION['state'] = $provider->getState();
header('Location: ' . $authorizationUrl);
exit();
} elseif ($_SERVER['REQUEST_METHOD'] === 'GET' && isset($_GET['code'])) {
// Validate the OAuth state parameter
if (empty($_GET['state']) || ($_GET['state'] !== $_SESSION['state'])) {
unset($_SESSION['state']);
exit('State value does not match the one initially sent');
}
// With the authorization code, we can retrieve access tokens and other data.
try {
// Get an access token using the authorization code grant
$accessToken = $provider->getAccessToken('authorization_code', [
'code' => $_GET['code']
]);
$_SESSION['access_token'] = $accessToken->getToken();
if ($accessToken->hasExpired()) {
$accessToken = $provider->getAccessToken('refresh_token', [
'refresh_token' => $existingAccessToken->getRefreshToken()
]);
}
Test calendar
`require_once "vendor/autoload.php";
use Microsoft\Graph\Connect\Constants;
use Microsoft\Graph\Graph;
$accessToken = $_SESSION['access_token'];
$user=false;
$graph = new Graph();
$graph->setAccessToken($accessToken);
//the sesion token for calendars expires faster than our token to stay in connect, so if it expires have the user sign back in
try {
$user = $graph->createRequest("GET", "https://graph.microsoft.com/v1.0/me/calendars")
->execute();
} catch (Exception $e) { <-------FAILS HERE
// sessionTimeout(); exit;
var_dump($e);
}
$ids = $user->getBody()['value'];
$selection = "";
foreach ($ids as $id) {
$calendarName = $id['name'];
$calendarId = $id['id'];
$selection .= '<option value="'.$calendarId.'">'.$calendarName.'</option>';
}`
The reply given after accessing
//Line breaks are for readability only
https://login.microsoftonline.com/common/oauth2/v2.0/authorize?
state={state}
&scope=openid%20profile%20offline_access%20user.read%20mailboxsettings.read%20calendars.readwrite
&response_type=code
&approval_prompt=auto
&redirect_uri=https%3A%2F%2{url}%2Fcallback
&client_id={clientID}
Contains only a code as shown
//Line breaks are for readability only
https://{url}/callback?
code={code}
As opposed to the expected
//Line breaks are for readability only
https://{url}/callback?
code={code}
&state={state}
This means that the 'Invalid auth state' error is generated
Steps to reproduce the behavior:
The user is logged in and their details are displayed.
I found this by seperating this check
if (!isset($providedState) || $expectedState != $providedState) {
return redirect('/')
->with('error', 'Invalid auth state')
->with('errorDetail', 'The provided auth state did not match the expected value');
}
Into
if (!isset($providedState)) {
return redirect('/')
->with('error', 'Invalid auth state')
->with('errorDetail', 'No provided state');
}
if ($expectedState != $providedState) {
return redirect('/')
->with('error', 'Invalid auth state')
->with('errorDetail', 'The provided auth state did not match the expected value');
}
hi I have followed the tutorial and I'm getting this error when I try to login with my organizations azure ad
Client error: GET https://graph.microsoft.com/v1.0/me?$select=displayName,mail,mailboxSettings,userPrincipalName
resulted in a 403 Forbidden
response: { "error": { "code": "UnknownError", "message": "\n<htm (truncated...)
when I log in with my personal Microsoft account all seem fine and it works as expected. I think it might have something to do with the API permissions for the owned app in azure ad, also how would I limit this to only allow logins for my organizational tenet only and not logins for personal accounts. thank you in advance for any help I'm new to the graph environment and laravel also please bear with me as it might take a bit of explaining for me to understand
I have followed every step correctly
After clicking sign in this error appears:
GuzzleHttp \ Exception \ RequestException
PHP 8.3.2
9.52.16
cURL error 60: SSL certificate problem: unable to get local issuer certificate (see https://curl.haxx.se/libcurl/c/libcurl-errors.html) for https://login.microsoftonline.com/common/oauth2/v2.0/token
sorry if it is not the right place to ask, but he found 100 libraries with 100 different functionalities, is it possible in this example to list the users of the domain to have the IDs, and thus validate with the users of another bd?
Hi!
I'm doing the Tutorial and when I sign in, the Php App shows me a welcome message with my name, but also, before the welcome message, appears "Invalid auth state" -"The provided auth state did not match the expected value".
Looking at the code, this message comes from callback() function from AuthController. The message shows up because sesession('oauthState') is null.
So..... at the same controller AuthController, when signing in with function signin(), the value of
sesession('oauthState') is set, is not null. But later, at the callback it has changed to null....
Please help....
Hi,
I try using this example with ADFS, but I receive error after the application forwarded to the adfs portal.
This error code is the 500 and I no have access to client ADFS.
Could someone help me please.
I'm getting error ERR_TOO_MANY_REDIRECTS when trying to log in, the request return statut 302 in an endless loop, it worked fine yesterday, today it's not working anymore, i tried it in private tab, clear cache and cookies still getting error
Is it possible to get this information without all of the Laravel bloatware?
I would love to be able to learn how to use this but I can't understand where the actual code resides within all the bloatware added by Laravel.
A simple and plain PHP project would be greatly appreciated.
Issues:
This means that it simply doesn't work because Azure doesn't work with plain HTTP in its response.
Hi,
I have gone through the example code and I noticed that there are only try functions but never an exception catching function? Will it throw any exceptions at all?
I am using the createRequest function and I encountered errors but there is no exception.
Regards,
Dennis
Hi there,
I'm trying to adapt the blade version you made to a rest one.
The purpose of the application is to get sent/received mail messages to put in a CRM database account.
in our endPoint method the user (Sales Rep) will provide his user/password, so then I used the post like this:
https://login.microsoftonline.com/{myTenantID}/oauth2/token
with the parameters:
grant_type=password,
client_id=myAppId,
client_secret=mySecret,
username=[email protected],
password=salesreppwd,
resource=https://graph.microsoft.com/,
scope=user.read,calendars.read,MailboxSettings.Read,Mail.read,Mail.Send
it works,I received access token and also refresh token, but I can only receive User.Read scope.
How can I change that to receive also calendars read/write and emails read/write scopes?
Thanks in advance
As per @jasonjoh 's suggestion to create a sepparate issue:
After signing in and navigating to calender and then letting it idle for a long time, I was greeted with a
'Undefined index: userTimeZone' in app/Http/Controllers/CalendarController.php
` // Get user's timezone
$timezone = TimeZones::getTzFromWindows($viewData['userTimeZone']);`
After digging around in code and google for some days i came to conclusion ( with my limited know-how in oop and even less in graph / laravel ) that its not an actual issue or bug, but rather a result of something not implemented in the demo (correct me If i'm wrong).
I think replicating the issue should be as simple as deleting cookies from browser that hold the session data to ones demo app.
As for solution i found a suggestion somewhere about creating a Laravel Middleware 'piece' that checks if the token is expired and then act accordingly.
I do have a workaround that works for me atm, but i dont feel like posting it... I'd rather copy good code than spread something that i'm not sure is safe.
So if a kind soul with the know-how could implement that into the demo
Edit: found the middleware suggestion.... It was the issue #4 from two and a half years ago.... :-/
Hi,
Just a small issue, when you get the final .md file you cannot view the overview as that link doesn't point to anything. The resource probably moved or if it's available anymore this should probably be updated to reflect that.
https://github.com/microsoftgraph/msgraph-training-phpapp/blob/master/graph/overview
TL;DR: ^^ doesn't exist anymore ^^
If a user has not logged in using their Microsoft credentials and attempts to go to the url http://localhost:8000/calendar by directly typing the URL into the address bar, the tutorial simply throws an error message saying No access token has been provided
.
What would be the best way to redirect to another URL when there is not a valid access token? For example, what if we wanted to redirect the user back to http://localhost:8000
?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.