I'm getting Google analytics using Google API. In order to get analytics I need to provide profile Id which looks like "ga:12345678".
The problem is that user can have many profiles. Is it possible to figure out profile Id from say Google tracking code (e.g. if I know tracking ID which looks like "UA-1234567-1")?
Are they related to each other at all?
Thanks
I had the same issue and I find out the simplest way to get google analytics profile id.
Log into Google Analytics
1.Access your site’s profile (get to the dashboard)
2.Your URL should look like:
https://www.google.com/analytics/web/#report/visitors-overview/a1234b23478970p987654/
/a1234b23478970p987654/
That last part, after the “p” is your Google Analytics Profile ID, in this case (this is a fake account) it is “987654”
You can programatically get the profiles that exist for a given WebPropertyId (UA code) using the management API (link below).
The HTTP call you make will look like this:
https://www.google.com/analytics/feeds/datasources/ga/accounts/[accountID]/webproperties/[webPropertyID]/profiles
Where accountID and webPropertyID will either be set to the specific values you are interested in or ~all to bring back everything the current user has access to.
If by convention you don't create multiple profiles under a Web Property then only the default profile will be returned for a given WebPropertyId, which means you will be getting a one-to-one mapping from WebPropertyId to profile id. This will allow you to look up a profile id from a WebPropertyId.
See here on the management API docs for more info: http://code.google.com/apis/analytics/docs/mgmt/mgmtFeedReference.html
I had just done this task of finding the profile ID by Tracking Code in Java. The key is that tracking code is used as web property Id and the profile is linked with web property through an internal web property id. So the steps are as below:
In Google developer console, set up a Service Accounts Client ID to get client email address, client Id and p12 file. Download the p12 and put to your server.
Authorize your Google Analytics account with client id and p12 file to obtain Analytics object
With Analytics object, you can obtain all web property objects, select the property with your tracking code as web property id and get its internal web property id
With Analytics object, iterate through all profile objects, select the profile which has internal web property id the same as obtained from step 2
The full code is as follows, the getProfileId() method will return the profile id you want:
import java.io.File;
import java.util.Arrays;
import org.apache.commons.lang.StringUtils;
import com.google.api.client.googleapis.auth.oauth2.GoogleCredential;
import com.google.api.client.http.HttpTransport;
import com.google.api.client.http.javanet.NetHttpTransport;
import com.google.api.client.json.JsonFactory;
import com.google.api.client.json.jackson2.JacksonFactory;
import com.google.api.services.analytics.Analytics;
import com.google.api.services.analytics.AnalyticsScopes;
import com.google.api.services.analytics.model.Profile;
import com.google.api.services.analytics.model.Profiles;
import com.google.api.services.analytics.model.Webproperties;
import com.google.api.services.analytics.model.Webproperty;
public class AnalyticsUtils {
public static final String APP_NAME = "<YOUR APP NAME>";
public static final String CLIENT_ID = "<YOUR CLIENT ID>";
public static final String CLIENT_EMAIL = "<YOUR CLIENT EMAIL>";
public static final String PATH_TO_P12= "<PATH TO YOUR P12 FILE>";
public static final String TRACKING_ID="<YOUR TRACKING CODE>";
public static Analytics initializeAnalytics() throws Exception {
final HttpTransport HTTP_TRANSPORT = new NetHttpTransport();
final JsonFactory JSON_FACTORY = new JacksonFactory();
GoogleCredential credential = new GoogleCredential.Builder()
.setTransport(HTTP_TRANSPORT)
.setJsonFactory(JSON_FACTORY)
.setServiceAccountId(CLIENT_EMAIL)
.setServiceAccountPrivateKeyFromP12File(new File(PATH_TO_P12))
.setServiceAccountScopes(
Arrays.asList(AnalyticsScopes.ANALYTICS_READONLY))
.build();
Analytics analytics = new Analytics.Builder(HTTP_TRANSPORT,
JSON_FACTORY, credential).setApplicationName(APP_NAME).build();
return analytics;
}
public static String getProfileId(Analytics analytics) throws Exception {
Webproperties webproperties = analytics.management().webproperties().list("~all").execute();
String internalPropertyId = StringUtils.EMPTY;
for (Webproperty webproperty: webproperties.getItems()) {
if (TRACKING_ID.equalsIgnoreCase(webproperty.getId())) {
internalPropertyId = webproperty.getInternalWebPropertyId();
break;
}
}
Profiles profiles = analytics.management().profiles()
.list("~all", "~all").execute();
for (Profile profile: profiles.getItems()) {
if (internalPropertyId.equalsIgnoreCase(profile.getInternalWebPropertyId())) {
return profile.getId();
}
}
return StringUtils.EMPTY;
}
}
What you're trying to obtain is called the tableId. The ID used in tracking code is called the webPropertyId. It's possible to create multiple profiles, with unique tableId's, for each web property.
You can get the tableId from the "Analytics Settings > Profile Settings" screen within GA (press 'edit' on one of the profiles). Then take the "Profile ID" field and append it to "ga:". You can also download the account details, including profile data, using the Account Feed: http://code.google.com/intl/en/apis/analytics/docs/gdata/gdataReferenceAccountFeed.html
I done this using Perl.
This is the url to get request
my $ url = qq~https://www.googleapis.com/analytics/v3/management/accounts/ACCOUNTID/webproperties/WEBPROPERTYID/profiles?key=APIKEY~;
use this url with Token to generate Data where you will find the ga id
Hope this helps.
Related
I am using below settings in ADAL to access Azure AD.
this is settings someone used and I found in internet
public const string ApplicationId = "your-application-id";
public const string ReturnUri = "http://your-uri.com/";
public const string Authority = "https://login.windows.net/common";
public const string GraphResourceUri = "https://graph.windows.net";
this is my setting
public static string ApplicationID = "xxxx-xxxx-xxxx-xxxx-xxxxx";
public static string ReturnUri = "http://myAppName register in AzureAD";
public static string tenanturl = "https://login.microsoftonline.com/xxx-xxx-xxx-xxx-xxx";
public static string GraphResourceUri = "https://graph.microsoft.com";
Problem:
I hope someone can confirm the following:
a) Is Authority is same as tenanturl ? which one to use: login.windows.net or login.microsoftonline.com
b) which to use for GrapResourceUri: graph.windows.net or graph.microsoft.com
c) are the settings in 1 and 2 complete? or there is more settings to add.
d) the token return from Azure AD is SAML or JWT token?
a) Is Authority is same as tenanturl ? which one to use: login.windows.net or login.microsoftonline.com
Authority should be https://login.microsoftonline.com/your-tenant-id-here.
You can use either the unique id for your AAD tenant or one of the verified domain names, e.g. https://login.microsoftonline.com/mytenant.onmicrosoft.com.
b) which to use for GrapResourceUri: graph.windows.net or graph.microsoft.com
If you want to call Azure AD Graph API, the first. If you want to call Microsoft Graph API, you use the second.
c) are the settings in 1 and 2 complete? or there is more settings to add.
Sadly the answer is it depends.
There are many flows for acquiring an access token in Azure AD, and which one you use (and thus which overload of AcquireAccessToken() you use) depends on the type of your application and what is the situation.
The settings here are enough for a native application (which yours is I guess since the Xamarin Forms tag is there).
I'm filling in the oauth_client_details table from a client registration service. I'm putting some data in JSON format in the additional_information field.
insert into oauth_client_details(client_id, client_secret, ..., additional_information) values
('app-client-id', 'app-client-secret', ..., '{"special-id":"abc-123"}');
I would like to store that data in the JWT but cannot see a way to access it. I see it getting loaded and parsed in JdbcClientDetailsService.loadClientByClientId and the related RowMapper but the data is not there when my token enhancer is called:
static class MyTokenEnhancer implements TokenEnhancer {
#Override
public OAuth2AccessToken enhance(OAuth2AccessToken accessToken, OAuth2Authentication authentication) {
// accessToken.additionalInformation is an empty map here!
return accessToken;
}
}
Is there another point in the flow where I can access and inject the value of special-id into the JWT?
I could only solve this by adding a custom field to oauth_client_details, load the detail record once again in TokenEnhancer.enhance() (Spring loads the record 6 times by this time, so another won't matter), then add the value from my custom field to the JWT as usual.
I could have used the additional_information field to store my custom data, but then I would need to parse the JSON. I see no point in doing that.
Here is my code, I need to setMandatory to 'false' because the resource provider does not return the 'state' parameter as the Oauth2 specification recommends.
#Bean
#Scope(value = "session", proxyMode = ScopedProxyMode.INTERFACES)
public OAuth2RestOperations restTemplate() {
OAuth2RestTemplate template = new OAuth2RestTemplate(resource(), new DefaultOAuth2ClientContext(accessTokenRequest));
AuthorizationCodeAccessTokenProvider authorizationCodeAccessTokenProvider = new AuthorizationCodeAccessTokenProvider();
authorizationCodeAccessTokenProvider.setStateMandatory(false);
AccessTokenProviderChain provider = new AccessTokenProviderChain(Arrays.asList(authorizationCodeAccessTokenProvider));
provider.setClientTokenServices(clientTokenServices());
template.setAccessTokenProvider(provider);
return template;
}
Here is the code from the github example that works with H2:
#Bean
#Scope(value = "session", proxyMode = ScopedProxyMode.INTERFACES)
public OAuth2RestOperations restTemplate() {
OAuth2RestTemplate template = new OAuth2RestTemplate(resource(), new DefaultOAuth2ClientContext(accessTokenRequest));
AccessTokenProviderChain provider = new AccessTokenProviderChain(Arrays.asList(new AuthorizationCodeAccessTokenProvider()));
provider.setClientTokenServices(clientTokenServices());
return template;
}
I changed the LONGVARBINARY to BLOB for all cases in schema.sql, in order to get the scripts to work with MySQL. I can verify that my database is created.
template.setAccessTokenProvider(provider); without this line, I still get the CSRF problems because the resource provider isn't returning the "state" param.
I am using an AuthorizationCodeResourceDetails just like the example as well. I also setup my accessTokenRequest and clientTokenServices identical to the example.
After the user authorizes the client and is redirected back, the code is exchanged for a token and things are working. I can see that my client does have an access token. I expect to see that access token stored in the database as well. I am creating the database schema on startup and the datasource appears to be setup properly. I don't get any errors during runtime that point to configuration issues either. Everything else is working as expected, I just don't get any data in any of the tables where I expect to see information about the access and refresh tokens sent back from the resource server.
So I have an asp.net application (using MVC5, ASP 4.5, EF) deployed on Azure. The application allows users to register and login.
However, once logged in, anyone can see everyone else's data.
What is the best practice to isolate the data belonging to different users so that each user can only see the data he/she creates?
Another small question is how does Facebook separates its users' data?
Thanks
For every piece of data a user creates, store their user ID and only allow users to see data that has their user ID. A couple of examples:
SQL:
SELECT UserDataID, Value FROM UserData WHERE UserID = #UserID;
Pass in the user's id to the #UserID parameter.
LINQ:
using (var entityFrameworkContext = new MyDataEntities())
{
var currentUserData = entityFrameworkContext.UserData.Where(userData -> userData.UserID = currentUserID);
}
Where currentUserID could be the user name or ID from forms authentication, for example: HttpContext.Current.User.Identity.Name.
The way in which I accomplished this was by the following.
In your controller you will need to use
public ActionResult Index()
{
var currentUser = manager.FindById(User.Identity.GetUserId());
return View(db.ToDoes.ToList().Where(todo => todo.User.Id == currentUser.Id));
}
You can then also create an admin role which can then view all the details of users and return ToList(). You then might want to put an [Authorize] method on it to only allow Admins access.
[Authorize(Roles="Admin")]
public async Task<ActionResult> All()
{
return View(await db.ToDoes.ToListAsync());
}
I found the following project of great help in understanding. https://github.com/rustd/AspnetIdentitySample
Hope this is of some help
I asked this question before which has got a very good response. But as I am new to asp.net (and jquery) cant understand how the program is flowing.
Summary:
I have created a Basic chat application. Now I am trying to add a advanced function like whenever a user is online (connected to a server), the server should show or broadcast the available online user's username to all the users connected to that server.
By referring the responses to the previous question (s0nica and VinayC), I modified my class file and jquery file, which are giving errors as shown in the below links. (I think I am very close)
Chat.cs (Two errors, I mentioned errors in between code comments)
file.js (Working fine, refer it if you need to)
Please have a look to the above files and assist me.
PS: In the previous post, I was thinking that if I change the Global.asax code, my problem will be solved.. which I realized later as wrong..
Your first error from:
Clients.joins(Context.ConnectionId, Caller.username, DateTime.Now);
Shold be:
Clients.All.joins(Context.ConnectionId, Clients.Caller.username, DateTime.Now);
Other errors associated with it: In your JS file it should be:
Line 15
chat.state.username = chatUsername;
Second error:
The error is exactly as it states, you do not have a toList function off of your dictionary object. Secondly you can't plainly convert a List or a string directly to a Chat object.
Based on your setup you currently dont have a proper "user" list to return. Right now you're saving a List to represent an individual user. You might want to try changing your dictionary object to be something like
static ConcurrentDictionary<string, User> _users = new ConcurrentDictionary<string, User>();
Where User is:
public class User
{
public string Name { get; set; }
public string ConnectionID { get; set; }
}
Then on your Joined function you could just do:
public void Joined()
{
User user = new User
{
Name = Clients.Caller.username,
ConnectionID = Context.ConnectionId
};
_users.TryAdd(user.ConnectionID, user);
Clients.All.joins(user.ConnectionID, user.Name, DateTime.Now);
}
Lastly your GetConnectedUsers would end up(make sure you're 'using System.Linq;'):
public List<User> GetConnectedUsers()
{
return _users.Values.ToList();
}
I probably went a little bit overboard but hopefully this helps!
If you need a reference to the change log from SignalR 0.5.3 to 1.0 alpha here's a great post on all of the modifications:
http://weblogs.asp.net/davidfowler/archive/2012/11/11/microsoft-asp-net-signalr.aspx